diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..93c4b27b4
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+github: processing
+custom: https://processingfoundation.org/
diff --git a/.gitignore b/.gitignore
index 367672981..27c953a9e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,4 @@ about/
contrib_generate/contribs.txt # File now built on the server side; don't need to track here
contrib_generate/contributions.txt # File now built on the server side; don't need to track here
*~
+/bin/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..9f20dd7ba
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,15 @@
+## Contributing to Processing
+
+Wow, thank you for helping us out!
+
+## Reporting Issues
+
+**[Here's how to report a bug with Processing.](https://github.com/processing/processing/wiki/Report-Bugs)**
+
+Before logging a new issue, please please please review [that document](https://github.com/processing/processing/wiki/Report-Bugs) closely. Processing is a complex project housed across several repositories. A quick read on your part now will save us all a lot of hassle later.
+
+## Other Contributions
+
+See the [Processing wiki](https://github.com/processing/processing/wiki#contribute) for how to contribute in other ways.
+
+Thank you!
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..71ae8ba7c
--- /dev/null
+++ b/ISSUE_TEMPLATE.md
@@ -0,0 +1,10 @@
+### Issue description
+
+
+
+### URL(s) of affected page(s)
+
+
+
+### Proposed fix
+
diff --git a/README.md b/README.md
index c0183179c..60a674da3 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,14 @@
+> ⚠️ This repository is now deprecated and will be archived soon. If you have any issues or want to submit a pull request, please direct them to the [processing-website](https://github.com/processing/processing-website) repo. Make sure to check the [README](https://github.com/processing/processing-website/blob/main/README.md) for information on how to contribute to the documentation.
+
+
+
Processing Documentation
==========
-This is the official source code for the Processing reference, examples, tutorials, and [processing.org](http://processing.org) web site.
+~~This is the official source code for the Processing reference, examples, tutorials, and [processing.org](http://processing.org) web site.~~
-If you have found an error in the Processing reference, examples, tutorials, or website you can file it here under the ["issues" tab](https://github.com/processing/processing-docs/issues).
+~~If you have found an error in the Processing reference, examples, tutorials, or website you can file it here under the ["issues" tab](https://github.com/processing/processing-docs/issues).~~
-The [processing](https://github.com/processing/processing) repository contains the source code for Processing itself. (Please use that link to file issues regarding the Processing software.)
+~~The [processing](https://github.com/processing/processing) repository contains the source code for Processing itself. (Please use that link to file issues regarding the Processing software.)~~
diff --git a/config-f.php b/config-f.php
deleted file mode 100644
index 500644b22..000000000
--- a/config-f.php
+++ /dev/null
@@ -1,47 +0,0 @@
- array('English', 'utf-8', true, $domain) //,
- //'zh' => array('Chinese Traditional', 'big5', false, $domain."zh/"),
- //'zh-cn' => array('Chinese Simplified', 'GB2312', false, $domain."zh-cn/"),
- //'fr' => array('French', 'utf-8', true, $domain."fr/"),
- //'id' => array('Indonesian', 'utf-8', false, $domain."id/"),
- //'it' => array('Italian', 'utf-8', true, $domain."it/"),
- //'jp' => array('Japanese', 'Shift_JIS', false, 'http://stage.itp.tsoa.nyu.edu/~tk403/proce55ing_reference_jp/'),
- //'kn' => array('Korean', 'utf-8', false, 'http://www.nabi.or.kr/processing/'),
- //'es' => array('Spanish', 'utf-8', true, $domain."es/"),
- //'tr' => array('Turkish', 'ISO-8859-9', true, $domain."tr/"),
- //'he' => array('Hebrew', 'Windows-1255', false, ''),
- //'ru' => array('Russian', 'ISO-8859-5', false, ''),
- //'pl' => array('Polish', 'ISO-8859-2', false, '')
- );
-// Langauges with finished references available to the public
-$FINISHED = array('en');
-
-// for reference index formatting
-$break_before = array('Shape', 'Color');
-
-?>
\ No newline at end of file
diff --git a/content/api_en/LIB_io/GPIO_digitalRead.xml b/content/api_en/LIB_io/GPIO_digitalRead.xml
index 2efc9fbb1..4a8c8d36d 100755
--- a/content/api_en/LIB_io/GPIO_digitalRead.xml
+++ b/content/api_en/LIB_io/GPIO_digitalRead.xml
@@ -14,20 +14,21 @@
@@ -44,7 +44,7 @@ void pinEvent(int pin) {
-You can use noInterrupts() and interrupts() in tandem to make sure no interrupts are occuring while your sketch is doing a particular task. By default, interrupts are enabled.
+You can use noInterrupts() and interrupts() in tandem to make sure no interrupts are occuring while your sketch is doing a particular task. By default, interrupts are enabled.
]]>
@@ -36,14 +38,13 @@ void setup() {
Unlike on Arduino, where pins are implicitly set to inputs by default, it is necessary
-to call this function for any pin you want to access, including input pins.
+to call this function for any pin you want to access, including input pins.
+
+Pull-up and pull-down resistors are very useful when connecting buttons and switches, since they will force the value of the pin in a specified electrical state when no electrical connection is made, and the pin would otherwise be left "floating".
+
+The ability to set (and clear) pull-up and pull-down resistors is currently limited to the Raspberry Pi running the Raspbian distribution. On other systems, a warning will be shown.
]]>
-The mode parameter determines when the function will return: GPIO.FALLING occurs when the level changes from high to low, GPIO.RISING when the level changes from low
-to high, and GPIO.CHANGE when either occurs.
+The mode parameter determines when the function will return: GPIO.FALLING occurs when the level changes from high to low, GPIO.RISING when the level changes from low to high, and GPIO.CHANGE when either occurs.
-This function returns true if the change, false if the timeout occured.
+The optional timeout parameter determines how many milliseconds the function will wait at the most. If the value of the input pin hasn't changed at this point, an exception is raised for this line. Without a timeout parameter the function will wait indefinitely until the input pin has changed to the desired state.
]]>
+When no period is specified, a default 1 kHz (1000 Hz) is used.
]]>GPIO
noInterrupts()
interrupts()
releaseInterrupt()
- waitForInterrupt()
+ waitFor()
releasePin()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-play()
-Start the oscillator
-
-
-
-stop()
-Stop the oscillator
-
-
-
-freq()
-Change the frequency of the oscillator
-
-
-
-width()
-Change the pulse width of the oscillator
-
-
-
-amp()
-Change the amplitude/volume of the oscillator
-
-
-
-add()
-Offset the output of the oscillator by given value
-
-
-
-pan()
-Move the sound in a stereo panorama
-
-
-
-set()
-Set multiple parameters at once
-
-
-
-Pulse(parent )
-
-
-
-parent
-PApplet: typically use "this"
-
-
-
-
-
-
-
-1.0
-
-Object
-
-Library
-
diff --git a/content/api_en/LIB_sound/SawOsc.xml b/content/api_en/LIB_sound/SawOsc.xml
index 514326e8f..979ca1bb5 100755
--- a/content/api_en/LIB_sound/SawOsc.xml
+++ b/content/api_en/LIB_sound/SawOsc.xml
@@ -9,7 +9,7 @@
Application
-
+../../../images/LIB_sound_SawOsc.png
-
-
-
-
-
-
-
-
-play()
-Start the oscillator
-
-
-
-stop()
-Stop the oscillator
-
-
-
-freq()
-Change the frequency of the oscillator
-
-
-
-amp()
-Change the amplitude/volume of the oscillator
-
-
-
-add()
-Offset the output of the oscillator by given value
-
-
-
-pan()
-Move the sound in a stereo panorama
-
-
-
-set()
-Set multiple parameters at once
-
-
-
-SqrOsc(parent )
-
-
-
-parent
-PApplet: typically use "this"
-
-
-
-
-
-
-
-1.0
-
-Object
-
-Library
-
diff --git a/content/api_en/LIB_sound/SinOsc.xml b/content/api_en/LIB_sound/SinOsc.xml
index 1f6c8ad1e..abec47858 100755
--- a/content/api_en/LIB_sound/SinOsc.xml
+++ b/content/api_en/LIB_sound/SinOsc.xml
@@ -9,7 +9,7 @@
Application
-
+../../../images/LIB_sound_SinOsc.png
-
-
-
-
-
-
-
-
-play()
-Start the oscillator
-
-
-
-stop()
-Stop the oscillator
-
-
-
-freq()
-Change the frequency of the oscillator
-
-
-
-amp()
-Change the amplitude/volume of the oscillator
-
-
-
-add()
-Offset the output of the oscillator by given value
-
-
-
-pan()
-Move the sound in a stereo panorama
-
-
-
-set()
-Set multiple parameters at once
-
-
-
-SinOsc(parent )
-
-
-
-parent
-PApplet: typically use "this"
-
-
-
-
-
-
-
-1.0
-
-Object
-
-Library
-
diff --git a/content/api_en/LIB_sound/SinOsc_play.xml b/content/api_en/LIB_sound/SinOsc_play.xml
index 31761bad6..4c89cd172 100755
--- a/content/api_en/LIB_sound/SinOsc_play.xml
+++ b/content/api_en/LIB_sound/SinOsc_play.xml
@@ -13,7 +13,7 @@
+
+Sound
+
+Sound
+
+Configuration
+
+Application
+
+
+
+
+
+
+
+
+AudioIn
+
+
+
\ No newline at end of file
diff --git a/content/api_en/LIB_sound/SoundFile.xml b/content/api_en/LIB_sound/SoundFile.xml
index db860e881..c6eb0d03c 100755
--- a/content/api_en/LIB_sound/SoundFile.xml
+++ b/content/api_en/LIB_sound/SoundFile.xml
@@ -9,7 +9,6 @@
Application
-
-
-
-
-
-
-
-
-
-play()
-Play the soundfile
-
-
-
-loop()
-Loop the soundfile
-
-
-
-cue()
-Set the starting position of the soundfile
-
-
-
-jump()
-Jump to a specific position in the file while continuing to play
-
-
-
-stop()
-Stop the soundfile
-
-
-
-rate()
-Change the playback rate of the soundfile
-
-
-
-amp()
-Change the amplitude/volume of the player
-
-
-
-add()
-Offset the output of the player by given value
-
-
-
-pan()
-Move the soundfile in a stereo panorama
-
-
-
-set()
-Set multiple parameters at once
-
-
-
-duration()
-Returns the duration of the soundfile
-
-
-
-sampleRate()
-Returns the sample rate of the soundfile
-
-
-
-frames()
-Returns the number of frames/samples of the soundfile
-
-
-
-channels()
-Returns the number of channels of the soundfile
-
-
-
-SoundFile(parent , path )
-
-
-
-parent
-PApplet: typically use "this"
-
-
-
-path
-Full Path to file or filename for data path
-
-
-
-
-
-
-
-1.0
-
-Object
-
-Library
-
diff --git a/content/api_en/LIB_sound/SoundFile_add.xml b/content/api_en/LIB_sound/SoundFile_add.xml
index 28df56508..2b92734e5 100755
--- a/content/api_en/LIB_sound/SoundFile_add.xml
+++ b/content/api_en/LIB_sound/SoundFile_add.xml
@@ -18,12 +18,12 @@ SoundFile file;
void setup() {
size(640, 360);
background(255);
-
+
// Load a soundfile from the /data folder of the sketch and play it back
file = new SoundFile(this, "sample.mp3");
file.play();
file.add(0.1);
-}
+}
void draw() {
}
@@ -32,7 +32,7 @@ void draw() {
diff --git a/content/api_en/LIB_sound/SoundFile_amp.xml b/content/api_en/LIB_sound/SoundFile_amp.xml
index 8fed77f35..34002bbd2 100755
--- a/content/api_en/LIB_sound/SoundFile_amp.xml
+++ b/content/api_en/LIB_sound/SoundFile_amp.xml
@@ -21,8 +21,8 @@ void setup() {
// Load a soundfile from the /data folder of the sketch and play it back
file = new SoundFile(this, "sample.mp3");
- file.play();
file.amp(0.5);
+ file.play();
}
void draw() {
diff --git a/content/api_en/LIB_sound/SoundFile_channels.xml b/content/api_en/LIB_sound/SoundFile_channels.xml
index 2e371f9e2..ace503d83 100755
--- a/content/api_en/LIB_sound/SoundFile_channels.xml
+++ b/content/api_en/LIB_sound/SoundFile_channels.xml
@@ -18,11 +18,11 @@ SoundFile file;
void setup() {
size(640, 360);
background(255);
-
+
// Load a soundfile from the /data folder of the sketch and get the number of channels
file = new SoundFile(this, "sample.mp3");
println(file.channels());
-}
+}
void draw() {
}
@@ -31,22 +31,7 @@ void draw() {
-
-file .channels()
-
-
-int
-
-
-
-1.0
-
-Method
-
-Library
-
-
diff --git a/content/api_en/LIB_sound/SoundFile_cue.xml b/content/api_en/LIB_sound/SoundFile_cue.xml
index 347d45dc4..bded003ce 100755
--- a/content/api_en/LIB_sound/SoundFile_cue.xml
+++ b/content/api_en/LIB_sound/SoundFile_cue.xml
@@ -21,33 +21,17 @@ void setup() {
// Load a soundfile from the /data folder of the sketch and play it back
file = new SoundFile(this, "sample.mp3");
- file.cue(15);
+ file.cue(3.5);
file.play();
}
void draw() {
}
-
]]>
second parameter supports only integer values.
+Cues the playhead to a fixed position in the soundfile. Note that cue() only affects the playhead for future calls to play(), but not to loop().
]]>
-
-file .cue(second)
-
-
-
-
-
-
-1.0
-
-Method
-
-Library
-
-
diff --git a/content/api_en/LIB_sound/SoundFile_duration.xml b/content/api_en/LIB_sound/SoundFile_duration.xml
index ca9e0e073..969d68a02 100755
--- a/content/api_en/LIB_sound/SoundFile_duration.xml
+++ b/content/api_en/LIB_sound/SoundFile_duration.xml
@@ -21,32 +21,16 @@ void setup() {
// Load a soundfile from the data folder of the sketch and get the duration of the file
file = new SoundFile(this, "sample.mp3");
- println("SFDuration= " + file.duration() + " seconds");
+ println("Duration= " + file.duration() + " seconds");
}
void draw() {
}
-
]]>
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-play()
-Start the oscillator
-
-
-
-stop()
-Stop the oscillator
-
-
-
-freq()
-Change the frequency of the oscillator
-
-
-
-amp()
-Change the amplitude/volume of the oscillator
-
-
-
-add()
-Offset the output of the oscillator by given value
-
-
-
-pan()
-Move the sound in a stereo panorama
-
-
-
-set()
-Set multiple parameters at once
-
-
-
-SqrOsc(parent )
-
-
-
-parent
-PApplet: typically use "this"
-
-
-
-
-
-
-
-1.0
-
-Object
-
-Library
-
diff --git a/content/api_en/LIB_sound/TriOsc.xml b/content/api_en/LIB_sound/TriOsc.xml
index 2ca49c832..d504de89a 100755
--- a/content/api_en/LIB_sound/TriOsc.xml
+++ b/content/api_en/LIB_sound/TriOsc.xml
@@ -9,7 +9,7 @@
Application
-
+../../../images/LIB_sound_TriOsc.png
-
-
-
-
-
-
-
-
-play()
-Start the oscillator
-
-
-
-stop()
-Stop the oscillator
-
-
-
-freq()
-Change the frequency of the oscillator
-
-
-
-amp()
-Change the amplitude/volume of the oscillator
-
-
-
-add()
-Offset the output of the oscillator by given value
-
-
-
-pan()
-Move the sound in a stereo panorama
-
-
-
-set()
-Set multiple parameters at once
-
-
-
-TriOsc(parent )
-
-
-
-parent
-PApplet: typically use "this"
-
-
-
-
-
-
-
-1.0
-
-Object
-
-Library
-
diff --git a/content/api_en/LIB_sound/Waveform.xml b/content/api_en/LIB_sound/Waveform.xml
new file mode 100644
index 000000000..4251ddd60
--- /dev/null
+++ b/content/api_en/LIB_sound/Waveform.xml
@@ -0,0 +1,107 @@
+
+
+
+Waveform
+
+Sound
+
+Analyzer
+
+Application
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+input()
+Define the audio input for the analyzer
+
+
+
+analyze()
+Gets the last nsamples captured from the connected input sound source, writes them
+ into this Waveform's `data` array, and returns it.
+
+
+
+stop()
+Stop the analyzer
+
+
+
+data
+`float[]` of length nsamples, with the sample amplitudes between `-1` and `1`
+
+
+
+Waveform(parent )
+
+
+
+parent
+PApplet: typically use "this"
+
+
+
+
+
+
+
+Object
+
+Library
+
+
diff --git a/content/api_en/LIB_sound/WhiteNoise.xml b/content/api_en/LIB_sound/WhiteNoise.xml
index 0f67dfb46..ba8d252c2 100755
--- a/content/api_en/LIB_sound/WhiteNoise.xml
+++ b/content/api_en/LIB_sound/WhiteNoise.xml
@@ -29,66 +29,7 @@ void draw() {
-
-
-
-
-
-
-
-
-play()
-Start the generator
-
-
-
-stop()
-Stop the generator
-
-
-
-amp()
-Change the amplitude/volume of the generator
-
-
-
-add()
-Offset the output of the generator by given value
-
-
-
-pan()
-Move the sound in a stereo panorama
-
-
-
-set()
-Set multiple parameters at once
-
-
-
-WhiteNoise(parent )
-
-
-
-parent
-PApplet: typically use "this"
-
-
-
-
-
-
-
-1.0
-
-Object
-
-Library
-
diff --git a/content/api_en/LIB_sound/WhiteNoise_add.xml b/content/api_en/LIB_sound/WhiteNoise_add.xml
index 1876dc1ab..a6da5916b 100755
--- a/content/api_en/LIB_sound/WhiteNoise_add.xml
+++ b/content/api_en/LIB_sound/WhiteNoise_add.xml
@@ -34,19 +34,4 @@ void draw() {
The .add() method is useful for modulating other audio signals.
]]>
-
-noise .add(add)
-
-
-
-
-
-
-1.0
-
-Method
-
-Library
-
-
diff --git a/content/api_en/LIB_sound/WhiteNoise_amp.xml b/content/api_en/LIB_sound/WhiteNoise_amp.xml
index 98ea36777..83eef598a 100755
--- a/content/api_en/LIB_sound/WhiteNoise_amp.xml
+++ b/content/api_en/LIB_sound/WhiteNoise_amp.xml
@@ -35,24 +35,4 @@ void draw() {
Changes the amplitude/volume of the noise generator. Allowed values are between 0.0 and 1.0.
]]>
-
-noise .amp(vol)
-
-
-
-
-
-
-
-
-
-
-
-1.0
-
-Method
-
-Library
-
-
diff --git a/content/api_en/LIB_sound/WhiteNoise_pan.xml b/content/api_en/LIB_sound/WhiteNoise_pan.xml
index 3bcfab0ec..ffb68b7cf 100755
--- a/content/api_en/LIB_sound/WhiteNoise_pan.xml
+++ b/content/api_en/LIB_sound/WhiteNoise_pan.xml
@@ -36,19 +36,4 @@ void draw() {
Pan the generator in a stereo panorama. -1.0 pans to the left channel and 1.0 to the right channel.
]]>
-
-noise .pan(pos)
-
-
-
-
-
-
-1.0
-
-Method
-
-Library
-
-
diff --git a/content/api_en/LIB_sound/WhiteNoise_play.xml b/content/api_en/LIB_sound/WhiteNoise_play.xml
index c25d29486..9dd12d80d 100755
--- a/content/api_en/LIB_sound/WhiteNoise_play.xml
+++ b/content/api_en/LIB_sound/WhiteNoise_play.xml
@@ -34,19 +34,4 @@ void draw() {
Starts the White Noise generator.
]]>
-
-noise .play()
-
-
-
-
-
-
-1.0
-
-Method
-
-Library
-
-
diff --git a/content/api_en/LIB_sound/WhiteNoise_set.xml b/content/api_en/LIB_sound/WhiteNoise_set.xml
index a4d965129..6ecf74ca1 100755
--- a/content/api_en/LIB_sound/WhiteNoise_set.xml
+++ b/content/api_en/LIB_sound/WhiteNoise_set.xml
@@ -41,19 +41,4 @@ void mousePressed() {
Sets amplitude, add and pan position with one method.
]]>
-
-noise .set(amp, add, pos)
-
-
-
-
-
-
-1.0
-
-Method
-
-Library
-
-
diff --git a/content/api_en/LIB_sound/WhiteNoise_stop.xml b/content/api_en/LIB_sound/WhiteNoise_stop.xml
index a5b932fd8..783fa8a36 100755
--- a/content/api_en/LIB_sound/WhiteNoise_stop.xml
+++ b/content/api_en/LIB_sound/WhiteNoise_stop.xml
@@ -38,19 +38,4 @@ void mousePressed() {
Stops the White Noise generator.
]]>
-
-noise .stop()
-
-
-
-
-
-
-1.0
-
-Method
-
-Library
-
-
diff --git a/content/api_en/LIB_sound/index.html b/content/api_en/LIB_sound/index.html
index 007b42f79..5bee0974e 100755
--- a/content/api_en/LIB_sound/index.html
+++ b/content/api_en/LIB_sound/index.html
@@ -1,71 +1,75 @@
-
-Sound
-
-
-
- The new Sound library for Processing 3 provides a simple way to work with audio. It can play, analyze, and synthesize sound. The library comes with a collection of oscillators for basic wave forms, a variety of noise generators, and effects and filters to alter sound files and other generated sounds. The syntax is minimal to make it easy to patch one sound object into another.
-
-
- The source code is available on the processing-sound GitHub repository. Please report bugs here. This library is only compatible with Processing 3.0+.
-
-
-
-
-
-
-
- I/O
-
- AudioDevice
- AudioIn
-
-
- Audio Files
-
-
- SoundFile
-
-
- Effects
-
-
-
- Analysis
-
-
-
-
-
-
-
- Noise
-
- WhiteNoise
- PinkNoise
- BrownNoise
-
-
- Oscillators
-
- SinOsc
- SawOsc
- SqrOsc
- TriOsc
- Pulse
-
-
- Envelopes
-
- Env
-
-
-
+
+Sound
+
+
+
+ The new Sound library for Processing 3 provides a simple way to work with audio. It can play, analyze, and synthesize sound. It provides a collection of oscillators for basic wave forms, a variety of noise generators, and effects and filters to play and alter sound files and other generated sounds. The syntax is minimal to make it easy to patch one sound object into another. The library also comes with example sketches covering many use cases to help you get started.
+
+
+ The source code is available on the processing-sound GitHub repository. Please report bugs here. This library is only compatible with Processing 3.0+.
+
+
+
+
+
+
+
+ Configuration
+
+ Sound
+
+
+ I/O
+
+ AudioIn
+
+
+ Sampling
+
+ SoundFile
+ AudioSample
+
+
+ Effects
+
+
+
+
+
+
+
+
+ Noise
+
+ WhiteNoise
+ PinkNoise
+ BrownNoise
+
+
+ Oscillators
+
+ SinOsc
+ SawOsc
+ SqrOsc
+ TriOsc
+ Pulse
+
+
+ Envelopes
+
+ Env
+
+
+ Analysis
+
+
+
diff --git a/content/api_en/LIB_svg/index.html b/content/api_en/LIB_svg/index.html
new file mode 100644
index 000000000..24737df1d
--- /dev/null
+++ b/content/api_en/LIB_svg/index.html
@@ -0,0 +1,167 @@
+
+SVG Export
+
+
+ The SVG library makes it possible to write SVG files directly from Processing. These vector graphics files can be scaled to any size and output at very high resolutions. The SVG library can flatten 3D data into a 2D vector file, but to export 3D data, use the DXF library. The source code is available on the Processing GitHub repository. Please report bugs here.
+
+ This library can be used with the core Processing function size(), or createGraphics(). See the examples below for different techniques.
+
+
+
+
+SVG Export (No Screen Display)
+
+This example draws a single frame to a SVG file and quits. (Note that no display window will open; this helps when you're trying to create massive SVG images that are far larger than the screen size.)
+
+import processing.svg.*;
+
+void setup() {
+ size(400, 400, SVG, "filename.svg");
+}
+
+void draw() {
+ // Draw something good here
+ line(0, 0, width/2, height);
+
+ // Exit the program
+ println("Finished.");
+ exit();
+}
+
+
+SVG Export (With Screen Display)
+
+To draw to the screen while also saving an SVG beginRecord()
+and endRecord() functions. Unlike the PDF renderer, the SVG renderer will only save the final frame of a sequence. This is slower, but is useful when you need to
+see what you're working on as it saves.
+
+import processing.svg.*;
+
+void setup() {
+ size(400, 400);
+ noLoop();
+ beginRecord(SVG, "filename.svg");
+}
+
+void draw() {
+ // Draw something good here
+ line(0, 0, width/2, height);
+
+ endRecord();
+}
+
+
+Single Frame from an Animation (With Screen Display)
+It's also possible to save one frame from a program with moving elements.
+Create a boolean variable to turn the SVG recording process on and off
+
+import processing.svg.*;
+
+boolean record;
+
+void setup() {
+ size(400, 400);
+}
+
+void draw() {
+ if (record) {
+ // Note that #### will be replaced with the frame number. Fancy!
+ beginRecord(SVG, "frame-####.svg");
+ }
+
+ // Draw something good here
+ background(255);
+ line(mouseX, mouseY, width/2, height/2);
+
+ if (record) {
+ endRecord();
+ record = false;
+ }
+}
+
+// Use a keypress so thousands of files aren't created
+void mousePressed() {
+ record = true;
+}
+
+
+SVG Files from 3D Geometry (With Screen Display)
+
+To create vectors from 3D data, use the beginRaw() and endRaw() commands.
+These commands will grab the shape data just before it is rendered to the screen.
+At this stage, your entire scene is nothing but a long list of lines and triangles.
+This means that a shape created with sphere() method will be made up of hundreds of
+triangles, rather than a single object.
+
+When using beginRaw() and endRaw(), it's possible to write to either a 2D or 3D renderer.
+For instance, beginRaw() with the SVG library will write the geometry as flattened triangles
+and lines.
+
+import processing.svg.*;
+
+boolean record;
+
+void setup() {
+ size(500, 500, P3D);
+}
+
+void draw() {
+ if (record) {
+ beginRaw(SVG, "output.svg");
+ }
+
+ // Do all your drawing here
+ background(204);
+ translate(width/2, height/2, -200);
+ rotateZ(0.2);
+ rotateY(mouseX/500.0);
+ box(200);
+
+ if (record) {
+ endRaw();
+ record = false;
+ }
+}
+
+// Hit 'r' to record a single frame
+void keyPressed() {
+ if (key == 'r') {
+ record = true;
+ }
+}
+
+
+Using createGraphics() to Create an SVG File
+
+To write a SVG file using only the createGraphics() command, rather than as
+part of a sketch, it's necessary to call dispose() on the PGraphicsSVG object.
+This is the same as calling exit(), but it won't quit the sketch.
+
+import processing.svg.*;
+
+PGraphics svg = createGraphics(300, 300, SVG, "output.svg");
+svg.beginDraw();
+svg.background(128, 0, 0);
+svg.line(50, 50, 250, 250);
+svg.dispose();
+svg.endDraw();
+
+
+
+Additional notes for the SVG renderer:
+
+
+
+- If you want 3D data, use the DXF recording library instead.
+
+
- Using hint(ENABLE_DEPTH_SORT) can improve the appearance of 3D geometry drawn to 2D file formats.
+
+
- Many methods, particularly pixel-based methods, don't make sense for SVG renderers. This includes: loadPixels, updatePixels, get, set, mask, filter, copy, blend, save, and image
+
+
- Again, exit() is really important when using SVG with size().
+
+
+
+
+
+
diff --git a/content/api_en/PImage_filter.xml b/content/api_en/PImage_filter.xml
index 30df9a9da..f30582ad1 100755
--- a/content/api_en/PImage_filter.xml
+++ b/content/api_en/PImage_filter.xml
@@ -156,7 +156,7 @@ POSTERIZE
Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges.
BLUR
-Executes a Guassian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Guassian blur of radius 1. Larger values increase the blur.
+Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur.
ERODE
Reduces the light areas. No parameter is used.
diff --git a/content/api_en/PImage_loadPixels.xml b/content/api_en/PImage_loadPixels.xml
index 23c5f9730..a9c353f84 100644
--- a/content/api_en/PImage_loadPixels.xml
+++ b/content/api_en/PImage_loadPixels.xml
@@ -34,8 +34,6 @@ void draw() {
pixels[] array. This function must always be called before reading from or writing to pixels[].
-
-Certain renderers may or may not seem to require loadPixels() or updatePixels(). However, the rule is that any time you want to manipulate the pixels[] array, you must have previously called loadPixels(), and after changes have been made, call updatePixels(). Even if the renderer may not seem to use this function in the current Processing release, this will always be subject to change.
]]>
diff --git a/content/api_en/PImage_pixels.xml b/content/api_en/PImage_pixels.xml
index 68203cae0..1f2a363e2 100755
--- a/content/api_en/PImage_pixels.xml
+++ b/content/api_en/PImage_pixels.xml
@@ -31,7 +31,7 @@ void draw() {
+
+
+
+
+
+
setup(), the draw() function continuously executes the lines of code contained inside its block until the program is stopped or noLoop() is called. draw() is called automatically and should never be called explicitly.
+Called directly after setup(), the draw() function continuously executes the lines of code contained inside its block until the program is stopped or noLoop() is called. draw() is called automatically and should never be called explicitly. All Processing programs update the screen at the end of draw(), never earlier.
-It should always be controlled with noLoop(), redraw() and loop(). If noLoop() is used to stop the code in draw() from executing, then redraw() will cause the code inside draw() to be executed a single time, and loop() will cause the code inside draw() to resume executing continuously.
+To stop the code inside of draw() from running continuously, use noLoop(), redraw() and loop(). If noLoop() is used to stop the code in draw() from running, then redraw() will cause the code inside draw() to run a single time, and loop() will cause the code inside draw() to resume running continuously.
The number of times draw() executes in each second may be controlled with the frameRate() function.
-It is common to call background() near the beginning of the draw() loop to clear the contents of the window, as shown in the first example above. Since pixels drawn to the window are cumulative, omitting background() may result in unintended results, especially when drawing anti-aliased shapes or text.
-
+It is common to call background() near the beginning of the draw() loop to clear the contents of the window, as shown in the first example above. Since pixels drawn to the window are cumulative, omitting background() may result in unintended results.
+
There can only be one draw() function for each sketch, and draw() must exist if you want the code to run continuously, or to process events such as mousePressed(). Sometimes, you might have an empty call to draw() in your program, as shown in the second example above.
]]>
diff --git a/content/api_en/endShape.xml b/content/api_en/endShape.xml
index a6c604615..eaa2d1e05 100755
--- a/content/api_en/endShape.xml
+++ b/content/api_en/endShape.xml
@@ -28,7 +28,7 @@ endShape();
endShape() function is the companion to beginShape() and may only be called after beginShape(). When endshape() is called, all of image data defined since the previous call to beginShape() is written into the image buffer. The constant CLOSE as the value for the MODE parameter to close the shape (to connect the beginning and the end).
+The endShape() function is the companion to beginShape() and may only be called after beginShape(). When endShape() is called, all of image data defined since the previous call to beginShape() is written into the image buffer. The constant CLOSE as the value for the MODE parameter to close the shape (to connect the beginning and the end).
]]>
diff --git a/content/api_en/environment/index.html b/content/api_en/environment/index.html
index 4d2e038d2..5d92731eb 100644
--- a/content/api_en/environment/index.html
+++ b/content/api_en/environment/index.html
@@ -531,8 +531,8 @@ Android Mode
Sketches written in this mode can be exported to run on Android phones and tablets.
- This mode is documented on the
- Processing for Android page of the Processing Wiki. To add this mode, click on
+ This mode is documented on the
+ Processing for Android page. To add this mode, click on
the mode button in the upper-right corner of the PDE and select "Add Mode..."
-->
@@ -574,7 +574,7 @@
- The Export information and
+ The Export information and
Tips page on the Processing Wiki covers the details of exporting Applications from Java mode.
diff --git a/content/api_en/exit.xml b/content/api_en/exit.xml
index 1df2bb8a0..e6ee94323 100755
--- a/content/api_en/exit.xml
+++ b/content/api_en/exit.xml
@@ -22,7 +22,7 @@ void mousePressed() {
draw() function exit automatically after the last line has run, but programs with draw() run continuously until the program is manually stopped or exit() is run.
+Quits/stops/exits the program. Programs without a draw() function stop automatically after the last line has run, but programs with draw() run continuously until the program is manually stopped or exit() is run.
Rather than terminating immediately, exit() will cause the sketch to exit after draw() has completed (or after setup() completes if called during the setup() function).
diff --git a/content/api_en/expand.xml b/content/api_en/expand.xml
index 30c9d4afe..f0f020319 100755
--- a/content/api_en/expand.xml
+++ b/content/api_en/expand.xml
@@ -32,7 +32,7 @@ println(imgs.length); // Prints "64"
newSize parameter provides precise control over the increase in size.
+Increases the size of a one-dimensional array. By default, this function doubles the size of the array, but the optional newSize parameter provides precise control over the increase in size.
When using an array of objects, the data returned from the function must be cast to the object array's data type. For example: SomeClass[] items = (SomeClass[]) expand(originalArray)
]]>
diff --git a/content/api_en/frustum.xml b/content/api_en/frustum.xml
index 5469e611d..f9645bd5a 100755
--- a/content/api_en/frustum.xml
+++ b/content/api_en/frustum.xml
@@ -25,7 +25,7 @@ Sets a perspective matrix as defined by the parameters.
A frustum is a geometric form: a pyramid with its top cut off. With the viewer's eye at the imaginary top of the pyramid, the six planes of the frustum act as clipping planes when rendering a 3D view. Thus, any form inside the clipping planes is rendered and visible; anything outside those planes is not visible.
-Setting the frustum has the effect of changing the perspective with which the scene is rendered. This can be acheived more simply in many cases by using perspective().
+Setting the frustum has the effect of changing the perspective with which the scene is rendered. This can be achieved more simply in many cases by using perspective().
Note that the near value must be greater than zero (as the point of the frustum "pyramid" cannot converge "behind" the viewer). Similarly, the far value must be greater than the near value (as the "far" plane of the frustum must be "farther away" from the viewer than the near plane).
diff --git a/content/api_en/get.xml b/content/api_en/get.xml
index c1307b3cd..be56dc889 100755
--- a/content/api_en/get.xml
+++ b/content/api_en/get.xml
@@ -31,10 +31,12 @@ rect(25, 25, 50, 50);
x and y parameters to get the value of one pixel. Get a section of the display window by specifying additional w and h parameters. When getting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current imageMode().
-
+Reads the color of any pixel or grabs a section of an image. If no parameters are specified, the entire image is returned. Use the x and y parameters to get the value of one pixel. Get a section of the display window by specifying additional w and h parameters. When getting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current imageMode().
+
If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only RGB values are returned by this function. For example, even though you may have drawn a shape with colorMode(HSB), the numbers returned will be in RGB format.
+If a width and a height are specified, get(x, y, w, h) returns a PImage corresponding to the part of the original PImage where the top left pixel is at the (x, y) position with a width of w a height of h.
+
Getting the color of a single pixel with get(x, y) is easy, but not as fast as grabbing the data directly from pixels[]. The equivalent statement to get(x, y) using pixels[] is pixels[y*width+x]. See the reference for pixels[] for more information.
]]>
diff --git a/content/api_en/green.xml b/content/api_en/green.xml
index 7d3ff0566..f1c38fe88 100755
--- a/content/api_en/green.xml
+++ b/content/api_en/green.xml
@@ -27,8 +27,8 @@ Extracts the green value from a color, scaled to match current colorMode()
The green() function is easy to use and understand, but it is slower than a technique called bit shifting. When working in colorMode(RGB, 255), you can acheive the same results as green() but with greater speed by using the right shift operator (>>) with a bit mask. For example, the following two lines of code are equivalent means of getting the green value of the color value c:
-float r1 = green(c); // Simpler, but slower to calculate
-float r2 = c >> 8 & 0xFF; // Very fast to calculate
+float g1 = green(c); // Simpler, but slower to calculate
+float g2 = c >> 8 & 0xFF; // Very fast to calculate
]]>
diff --git a/content/api_en/include/ArrayList.xml b/content/api_en/include/ArrayList.xml
index 1cf04f77d..8feb4dc3a 100644
--- a/content/api_en/include/ArrayList.xml
+++ b/content/api_en/include/ArrayList.xml
@@ -64,7 +64,7 @@ An ArrayList stores a variable number of objects. This is similar to maki
An ArrayList is a resizable-array implementation of the Java List interface. It has many methods used to control and search its contents. For example, the length of the ArrayList is returned by its size() method, which is an integer value for the total number of elements in the list. An element is added to an ArrayList with the add() method and is deleted with the remove() method. The get() method returns the element at the specified position in the list. (See the above example for context.)
-For a list of the numerous ArrayList features, please read the Java reference description.
+For a list of the numerous ArrayList features, please read the Java reference description.
]]>
@@ -46,11 +43,11 @@ println(quoted); // This one has "quotes"
+
+
+
+
-Send and receive data over the Internet through simple clients and servers.
- + +Create SVG files.
+Send data between Processing and external hardware through serial communication (RS-232).
diff --git a/content/api_en/loadJSONArray.xml b/content/api_en/loadJSONArray.xml index d7b7444ac..da22530e9 100755 --- a/content/api_en/loadJSONArray.xml +++ b/content/api_en/loadJSONArray.xml @@ -13,24 +13,26 @@
pixels[] array. This function must always be called before reading from or writing to pixels[]. Subsequent changes to the display window will not be reflected in pixels until loadPixels() is called again.
-
-Certain renderers may or may not seem to require loadPixels() or updatePixels(). However, the rule is that any time you want to manipulate the pixels[] array, you must have previously called loadPixels(), and after changes have been made, call updatePixels(). Even if the renderer may not seem to use this function in the current Processing release, this will always be subject to change.
+Loads the pixel data of the current display window into the pixels[] array. This function must always be called before reading from or writing to pixels[]. Subsequent changes to the display window will not be reflected in pixels until loadPixels() is called again.
]]>
diff --git a/content/api_en/loadStrings.xml b/content/api_en/loadStrings.xml
index 50a71d6cf..321fa0140 100755
--- a/content/api_en/loadStrings.xml
+++ b/content/api_en/loadStrings.xml
@@ -11,7 +11,7 @@
If the file contains a header row, include "header" in the options parameter. If the file does not have a header row, then simply omit the "header" option.
-When specifying both a header and the file type as the options parameter, separate the options with commas, as in: loadTable("data.csv", "header, tsv")
+Some CSV files contain newline (CR or LF) characters inside cells. This is rare, but adding the "newlines" option will handle them properly. (This is not enabled by default because the parsing code is much slower.)
+
+When specifying multiple options, separate them with commas, as in: loadTable("data.csv", "header, tsv")
All files loaded and saved by the Processing API use UTF-8 encoding.
]]>
diff --git a/content/api_en/match.xml b/content/api_en/match.xml
index 1db3a9f3a..92d1b2fdf 100755
--- a/content/api_en/match.xml
+++ b/content/api_en/match.xml
@@ -51,7 +51,7 @@ To use the function, first check to see if the result is null. If the result is
If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Element [0] of a regular expression match returns the entire matching string, and the match groups start at element [1] (the first group is [1], the second [2], and so on).
-The syntax can be found in the reference for Java's Pattern class. For regular expression syntax, read the Java Tutorial on the topic.
+The syntax can be found in the reference for Java's Pattern class. For regular expression syntax, read the Java Tutorial on the topic.
]]>
diff --git a/content/api_en/matchAll.xml b/content/api_en/matchAll.xml
index 56feb6b5b..4f0345fbe 100644
--- a/content/api_en/matchAll.xml
+++ b/content/api_en/matchAll.xml
@@ -33,7 +33,7 @@ To use the function, first check to see if the result is null. If the result is
If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Assuming a loop with counter variable i, element [i][0] of a regular expression match returns the entire matching string, and the match groups start at element [i][1] (the first group is [i][1], the second [i][2], and so on).
-The syntax can be found in the reference for Java's Pattern class. For regular expression syntax, read the Java Tutorial on the topic.
+The syntax can be found in the reference for Java's Pattern class. For regular expression syntax, read the Java Tutorial on the topic.
]]>
diff --git a/content/api_en/mouseWheel.xml b/content/api_en/mouseWheel.xml
index 02c01cd7a..0a2344176 100755
--- a/content/api_en/mouseWheel.xml
+++ b/content/api_en/mouseWheel.xml
@@ -26,7 +26,7 @@ void mouseWheel(MouseEvent event) {
mouseWheel() function returns positive values when the mouse wheel is rotated down (toward the user), and negative values for the other direction (up or away from the user). On OS X with "natural" scrolling enabled, the values are opposite.
+The code within the mouseWheel() event function is run when the mouse wheel is moved. (Some mice don't have wheels and this function is only applicable with mice that have a wheel.) The getCount() function used within mouseWheel() returns positive values when the mouse wheel is rotated down (toward the user), and negative values for the other direction (up or away from the user). On OS X with "natural" scrolling enabled, the values are opposite.
Mouse and keyboard events only work when a program has draw(). Without draw(), the code is only run once and then stops listening for events.
]]>
diff --git a/content/api_en/nf.xml b/content/api_en/nf.xml
index f1e6123dd..295db43ac 100755
--- a/content/api_en/nf.xml
+++ b/content/api_en/nf.xml
@@ -26,11 +26,16 @@ String se = nf(e, 5, 3);
println(se); // Prints "00040.200"
String sf = nf(f, 3, 5);
println(sf); // Prints "009.01200"
+
+String sf2 = nf(f, 0, 5);
+println(sf2); // Prints "9.01200"
+String sf3 = nf(f, 0, 2);
+println(sf3); // Prints "9.01"
]]>
+
size() in a program without a setup() and used within setup() when a program has one. The pixelDensity() should only be used with hardcoded numbers (in almost all cases this number will be 2) or in combination with displayDensity() as in the third example above.
-
+
+When the pixel density is set to more than 1, it changes all of the pixel operations including the way get(), set(), blend(), copy(), and updatePixels() all work. See the reference for pixelWidth and pixelHeight for more information.
+
To use variables as the arguments to pixelDensity() function, place the pixelDensity() function within the settings() function. There is more information about this on the settings() reference page.
-
]]>
+
+
+
+
+
+scale(2.0) increases the dimension of a shape by 200%.
-Transformations apply to everything that happens after and subsequent calls to the function multiply the effect. For example, calling scale(2.0) and then scale(1.5) is the same as scale(3.0). If scale() is called within draw(), the transformation is reset when the loop begins again. Using this fuction with the z parameter requires using P3D as a parameter for size(), as shown in the third example above. This function can be further controlled with pushMatrix() and popMatrix().
+Transformations apply to everything that happens after and subsequent calls to the function multiply the effect. For example, calling scale(2.0) and then scale(1.5) is the same as scale(3.0). If scale() is called within draw(), the transformation is reset when the loop begins again. Using this function with the z parameter requires using P3D as a parameter for size(), as shown in the third example above. This function can be further controlled with pushMatrix() and popMatrix().
]]>
diff --git a/content/api_en/shorten.xml b/content/api_en/shorten.xml
index 82961260a..41746c5ad 100755
--- a/content/api_en/shorten.xml
+++ b/content/api_en/shorten.xml
@@ -20,7 +20,7 @@ println(sa2); // 'sa2' now contains OH, NY
+
![]() |
@@ -12,22 +11,22 @@ |||
|
|
- ||
![]() |
@@ -38,7 +37,7 @@ Books. Processing books cove
» Order Print/EBook from O'Reilly |
||
|
+ |
+ ||
![]() |
+
+
+ Processing for Android: Create Mobile, Sensor-Aware, and VR Applications Using Processing |
+ ||
|
+ |
+ ||
![]() |
+ Coding Art: The Four Steps to Creative Programming with the Processing Language + Yu Zhang, Mathias Funk. + Published January 2021, Apress. 280 pages. Paperback. + » Order from Apress + » Order from Amazon + + + The authors write, "Finally, a book on creative programming, written directly for artists and designers! Rather than following a computer science curriculum, this book is aimed at creatives who are working in the intersection of design, art, and education. In this book you'll learn to apply computation into the creative process by following a four-step process, and through this, land in the cross section of coding and art, with a focus on practical examples and relevant work structures. You'll follow a real-world use case of computation art and see how it relates back to the four key pillars, and addresses potential pitfalls and challenges in the creative process. All code examples are presented in a fully integrated Processing example library, making it easy for readers to get started." + |
+ ||
|
+ |
+ ||
![]() |
+ Pro Processing for Images and Computer Vision with OpenCV + Bryan WC Chung. + Published 2017, APress. Paperback, eBook. + » Order from APress + + The Publisher writes, "Pro Processing for Images and Computer Vision with OpenCV is a step-by-step training tool that guides you through a series of worked examples in linear order. Each chapter begins with a basic demonstration, including the code to recreate it on your own system. Then comes a creative challenge by which to engage and develop mastery of the chapter’s topic. The book also includes hints and tips relating to visual arts, interaction design, and industrial best practices. This book is intended for any developer of artistic and otherwise visual applications, such as in augmented reality and digital effects, with a need to manipulate images, and to recognize and manipulate objects within those images. The book is specifically targeted at those making use of the Processing language that is common in artistic fields, and to Java programmers because of Processing’s easy integration into the Java programming environment." + |
+ ||
|
+ |
+ ||
![]() |
+ Programming 101: The How and Why of Programming Revealed Using the Processing Programming Language + Jeanine Meyer. + Published 2018, APress. Paperback, eBook. + » Order from Apress + + The Publisher writes, "Understand the importance of programming, even if you’ve never programmed before! This book will teach you the basics of programming using the Processing programming language. You will create your own Processing sketches, using personal images, themes, or hobbies that you enjoy. The chapters in the book will demonstrate the process of programming, starting with formulating an idea, planning, building on past projects, and refining the work, similar to writing an essay or composing a song. This approach will guide you to make use of logic and mathematics to produce beautiful effects. The term for program in Processing is sketch, though the sketches featured in this book are far more than static drawings; they incorporate interaction, animation, video, audio, and accessing files on the local computer and on the Web. Technical features are introduced and explained in the context of complete examples: games (Snake, Hangman, jigsaw, slingshot), making a collage of family images and video clips, preparing directions for folding an origami model, rotating objects in 3D, and others." + |
+ ||
|
|
||
|
|
@@ -130,14 +204,14 @@ Generative Design Hartmut Bohnacker, Benedikt Gross, Julia Laub, and Claudius Lazzeroni. August 2012, Princeton Architectural Press. 472 pages. - Originally published in German November 2009, Schmidt Hermann Verlag. 500 pages. + Originally published in German November 2009, Schmidt Hermann Verlag. 500 pages. » Order from Amazon.com This book is extraordinary; the design is clear and the production quality is fantastic. This is the design book about Processing that we've hoped for. Unlike most other Processing books, it doesn't discuss programming basics so it's free to start with exciting examples. The publisher promotes, "Generative design is a revolutionary new method of creating artwork, models, and animations from sets of rules, or algorithms. By using accessible programming languages such as Processing, artists and designers are producing extravagant, crystalline structures that can form the basis of anything from patterned textiles and typography to lighting, scientific diagrams, sculptures, films, and even fantastical buildings. Opening with a gallery of thirty-five illustrated case studies, Generative Design takes users through specific, practical instructions on how to create their own visual experiments by combining simple-to-use programming codes with basic design principles. A detailed handbook of advanced strategies provides visual artists with all the tools to achieve proficiency. Both a how-to manual and a showcase for recent work in this exciting new field, Generative Design is the definitive study and reference book that designers have been waiting for." More information about buying this book in German, as well as the complete source code for the examples, are at the book's website. - |
+
|
|
|||
![]() |
+ Processing: An Introduction to Programming + Jeffrey L. Nyhoff, Larry R. Nyhoff. + Published May 2017, CRC Press. 544 pages. eBook, Paperback. + » Order from CRC Press + + » Order from Amazon.com + + The publisher writes, "The book uses Processing’s capabilities for graphics and interactivity in order to create examples that are simple, illustrative, interesting, and fun. It is designed to appeal to a broad range of readers, including those who want to learn to program to create digital art, as well as those who seek to learn to program to process numerical information or data. It can be used by students and instructors in a first course on programming, as well as by anyone eager to teach them self to program." + + The publisher lists: +
|
+ ||
|
+ |
+ ||
![]() |
@@ -209,13 +311,11 @@ |||
|
|
||
![]() |
Processing: Creative Coding and Computational Art (Foundation) @@ -227,11 +327,10 @@ Books. Processing books cove
|
||
|
|
||
+ | ![]() |
- Programming Interactivity + | Programming Interactivity Joshua Noble. Published January 2012, O'Reilly. 728 pages. Paperback. » Order from Amazon.com - The O'Reilly website says, "Make cool stuff. If you're a designer or artist without a lot of programming experience, this book will teach you to work with 2D and 3D graphics, sound, physical interaction, and electronic circuitry to create all sorts of interesting and compelling experiences -- online and off. Programming Interactivity explains programming and electrical engineering basics, and introduces three freely available tools created specifically for artists and designers: Processing, Arduino, and OpenFrameworks." |
-
|
@@ -296,7 +394,6 @@ |||
|
@@ -317,15 +414,12 @@ |||
|
|
||
@@ -335,20 +429,16 @@ Books. Processing books cove
Andrew Richardson. |
|||
|
|
||
|
|
|
+ |
![]() |
+
+
+ Creating Procedural Artworks with Processing |
+ ||
|
+ |
+ ||
![]() |
+ O Código Transcendente: Uma Introdução Prática à Programação e Arte Gerativa + Mateus Berruezo. + Published December 2019. 270 pages. PDF, Web. + Text in Portuguese. + » Download + » Read online + + + Este livro é um guia de programação com enfoque prático considerando o contexto da arte gerativa e do pensamento computacional. Ele conta com explicações e exemplos visuais cuidadosamente projetados para serem de valor tanto para programadores quanto artistas. As aplicações e estudos de caso foram direcionados para a linguagem Processing cuja própria filosofia segue o princípio da exploração do artístico através do código. + |
+ ||
|
+ |
+ ||
![]() |
Einführung ins Programmieren mit Processing - Matthias Wolf. - Published August 2013. 178 pages. PDF, Paperback. - Text in German. - » Order Print/EBook from lulu.com - - Die eigenständige Programmiersprache Processing basiert auf Java und ähnelt diesem sehr, verbirgt aber gleichzeitig viel von dessen Komplexität. Dadurch ist Processing für den Programmieranfänger ideal geeignet, um sich Konzepte des Programmierens zu erschließen und bewahrt gleichzeitig die Möglichkeit eines späteren Umstiegs. Dennoch ist die Sprache keineswegs nur für triviale Anfängeraufgaben geeignet: speziell im Bereich der graphischen Datenverarbeitung spielt Processing seine Stärken aus. -Dieses Buch richtet sich in erster Linie an den Einsteiger, den es an die Bewältigung auch komplexerer Aufgaben heranführt, wobei grundlegende Konzepte der imperativen und der objektorientierten Programmierung vorgestellt werden. Auch notwendige theoretische Hintergründe kommen dabei nicht zu kurz. Ausführlich kommentierter Beispielcode erschließt Konzepte und Sprache. Aber auch der routinierte Programmierer, der sich "nur" eine neue Sprache erschließen will, wird fündig! -Aus dem Inhalt: Datentypen — Variablen — Arrays (ein- und mehrdiomensional) — Flusssteuerung — Methoden — Objektorientiertes Programmieren — 2D-Graphik — 3D-Graphik — Dateizugriff — PDF — QuickTimeTM — Arduino®-Mikrocontroller — Alphabetischer Index
+ Matthias Wolf. Die eigenständige Programmiersprache Processing basiert auf Java und ähnelt diesem sehr, verbirgt aber gleichzeitig viel von dessen Komplexität. Dadurch ist Processing für den Programmieranfänger ideal geeignet, um sich Konzepte des Programmierens zu erschließen und bewahrt gleichzeitig die Möglichkeit eines späteren Umstiegs. Dennoch ist die Sprache keineswegs nur für triviale Anfängeraufgaben geeignet: speziell im Bereich der graphischen Datenverarbeitung spielt Processing seine Stärken aus. +Dieses Buch richtet sich in erster Linie an den Einsteiger, den es an die Bewältigung auch komplexerer Aufgaben heranführt, wobei grundlegende Konzepte der imperativen und der objektorientierten Programmierung vorgestellt werden. Auch notwendige theoretische Hintergründe kommen dabei nicht zu kurz. Ausführlich kommentierter Beispielcode erschließt Konzepte und Sprache. Aber auch der routinierte Programmierer, der sich "nur" eine neue Sprache erschließen will, wird fündig! +Aus dem Inhalt: Datentypen — Variablen — Arrays (ein- und mehrdiomensional) — Flusssteuerung — Methoden — Objektorientiertes Programmieren — 2D-Graphik — 3D-Graphik — Dateizugriff — PDF — QuickTimeTM — Arduino®-Mikrocontroller — Alphabetischer Index |
||
|
- |
- ||
|
-
- Processing is also discussed through examples and projects in the following books:
-
- - - - - 10 PRINT CHR$(205.5+RND(1)); : GOTO 10 By Nick Montfort, Patsy Baudoin, John Bell, Ian Bogost, Jeremy Douglass, Mark C. Marino, Michael Mateas, Casey Reas, Mark Sample, Noah Vawter. Examples use Processing to explore a modern interpretation of a 1982 Commodore 64 program. - - - - Make: Getting Started with Arduino By Massimo Banzi. Examples use Processing to communicate with an Arduino board. - - - - Building Wireless Sensor Networks: with ZigBee, XBee, Arduino, and Processing By Robert Faludi. Network examples use Processing. - - - - Physical Computing: Sensing and Controlling the Physical World with Computers - By Dan O'Sullivan and Tom Igoe. Examples using Processing for RS-232 communication and - computer vision. - - - - Aesthetic Computing. - Edited by Paul Fishwick. Casey Reas and Ben Fry contributed a chapter entitled - "Processing Code: Programming within the Context of Visual Art and Design." - - - - Hacking Roomba: ExtremeTech By Tod E. Kurt. Processing is introduced and used to design an application to control a Roomba (a robot vacuum cleaner). - - - Analog In, Digital Out By Brendan Dawes. Numerous projects created with Processing are illustrated and discussed. |
-
Earlier releases have been removed because we can only support the current versions of the software. To update old code, read the changes page. Changes for each release can be found in revisions.txt. If you have problems with the current release, please file a bug so that we can fix it. Older releases can also be built from the source. Read More about the releases and their numbering. To use Android Mode, Processing 3 or later is required.
+The changes document covers incremental updates between 4.x releases, and is especially important to read for pre-releases.
+-
|
-
-
-
-
-
- Processing is open source, free software. All donations fund the Processing Foundation, a nonprofit organization devoted to advancing the role of programming within the visual arts through developing Processing. - - - - - - - - - |
-
- -
|
-
- -The Processing Foundation maintains a fellowship program that supports the development and expansion of Processing and its affiliated projects. Work done by fellows is supported through funding and mentorship from The Processing Foundation. The projects done so far have all been undertaken in parallel with each of the fellows’ practices as artists. - - -- ![]() ![]()
-- - -Wilm Thoben (2013-14) - -
-Thoben developed a new core Sound library from fall 2013 through winter 2014. This library is now released with Processing 3.0.
- - ![]() ![]()
-- - -Lauren McCarthy (2013) - -
-McCarthy started the work that has now become p5.js in spring, summer, and fall 2013. p5.js is a JavaScript interpretation of Processing.
- - ![]() ![]()
-- - -Greg Borenstein (2013) - -
-Borenstein expanded and released the OpenCV library in spring and summer 2013.
- |
-
-
|
-
- - Since its inception in 2001, Processing has sought to bridge the traditionally divided cultures of the arts and the sciences. The mission of the Processing Foundation is to link these two cultures so they can be used within a diverse constituency, by way of developing the Processing software. For those with a tendency to think in numbers, Processing introduces a language of the visual arts through a more familiar computer science vocabulary. Likewise, the software is structured through an image-based framework, making it accessible to visual thinkers. Core computer science concepts like variables, functions, and conditionals are taught side by side with visual basics like image, shape, and color. - - -- The key to our philosophy is the merging between the two: we see software as a medium, or something that connects two things. We view it as a means for making, and see our role as providing a new medium to artists and users across a variety of fields. At a time when our society requires a literacy and sensitivity to media of all kinds, we see ourselves making this possible for a broad spectrum of constituencies. - - - -- Processing serves a wide range of communities in different contexts, from the university classroom to the tinkerer’s garage, used by everyone from the professional to the hobbyist. Within education at a university level, we have seen Processing leveraged as a classroom tool across disciplines as varied as computer science, English, art, architecture, design, and the digital humanities. In the last few years, it has begun to become a presence in high school and middle school classrooms, being particularly effective when used to teach science, math, and more generally, computer science. For example, the Kahn Academy now uses Processing’s tutorials and language in their beginning computer science instruction. In areas of professional development, Processing has become enfolded into the practices of interface and communication designers, artists and media artists, photographers, architects, and filmmakers. It also has a substantial role in the communities of makers and amateurs, and among hackerspaces and gatherings of hobbyists. - - - -- The growing use of Processing in the classroom over the last twelve years has pointed toward a direction to rethink the way students are taught to program. Instead of learning a specific vocational skill (such as any one certain programming language or software), the teaching of Processing follows from a philosophy that advocates for a more generalized and strategic way of thinking. Because technology changes at such a rapid pace, the goal of any education in software has to teach the fundamentals of programming. With knowledge of such a foundation, a student is able to learn any other piece of software. Processing was specifically designed to relate to other languages, so a working knowledge of it means that a student can become well-versed in others that are more domain-specific, in relatively little time. Also, it uses a visual framework, so as to be more accessible to people who don’t naturally think like mathematicians or computer scientists. This has opened the door for software to become part of an artist’s toolkit in a way never before seen. - - -- The use of Processing within the visual arts and design fields has grown continuously since the software was first released. Appearing at a critical moment when artists began introducing new media and technology into their practices, Processing has allowed for thousands of creative professionals to leverage it as a medium, changing the landscape of the arts at the beginning of the 21st century. Software is still a nascent medium for artists and designers, and part of The Processing Foundation’s mission is to nurture this trajectory to be both widely used and accepted. - - -- Within technology, Processing has made it possible to understand massive data sets in a visual and more accessible way. It has also helped foster the connection between engineering and visual design that has been pushed to the fore by Apple and others. - - - |
-
|
-
- - The Processing Foundation was founded in 2012 with the two-fold mission to promote software literacy within the visual arts, and visual literacy within technology-related fields. Our primary goal is to empower people of all interests and backgrounds to learn how to program, so as to facilitate a sophisticated way of thinking about and creating media at a time when such knowledge is crucial. We do this by developing and distributing a group of related software projects, which includes Processing (Java), p5.js (Javascript), and Processing.py (Python). - - --We serve a growing community of artists, designers, educators, programmers, engineers, and anyone in between who has an inclination toward both the arts and technology. Core to our belief is that learning how to program is a process of learning how to think, rather than acquiring a certain skillset, so that this knowledge may be applied to any number of fields, from creating artworks to imagining new technologies. We view Processing as a means to bridge seemingly disparate disciplines, providing platforms for collaboration between communities that might not otherwise have had access to each other. We also envision Processing as a new tool for both artists and technologists to use in their work, as a medium and as a context. We see ourselves situated at the place of convergence between the arts and technology, facilitating the pursuit and literacy of both. - - --Processing is primarily developed by a dedicated group affiliated with Fathom Information Design (Boston), the UCLA Arts Software Studio (Los Angeles), and ITP at NYU (New York City). - - -- The Processing Foundation supports a fellowship program to initiate and develop research projects for the Processing software. - - --We are supported by our community and actively seek donations through downloads of Processing. - - --Contact us at foundation@processing.org - - - |
-
- -
|
-
- - Individuals making $5 to $100 donations are the largest source of income for the Processing Foundation. We’re grateful to all who have donated and we’re proud to be supported by the community. You can donate when you download the software here. - - -- The University of Denver and the Emergent Digital Practices program sponsored a Processing 3.0 development meeting in November 2014. We thank Chris Coleman and Laleh Mehran for arranging this session and gracefully hosting us. - - -- The Google Summer of Code program has provided and excellent source of energy and new development through supporting students to work with us. This program has now supported Processing for four years, 2010 to 2014. It has provided the base for many important enhancements to the software. - - -- In 2013, O'Reilly Media and Arduino made donations to the Processing Foundation. - - -- Prior to incorporating as a Foundation, Processing received key funding and support from several organizations and companies. These commitments enabled a series of pivotal improvements to the software: - - -
|
-
-
- |
- - Ben Fry is principal of Fathom, a design and software consultancy located in Boston. He received his doctoral degree from the Aesthetics + Computation Group at the MIT Media Laboratory, where his research focused on combining fields such as computer science, statistics, graphic design, and data visualization as a means for understanding information. After completing his thesis, he spent time developing tools for visualization of genetic data as a postdoc with Eric Lander at the Eli and Edythe L. Broad Institute of MIT and Harvard. During the 2006-2007 school year, Ben was the Nierenberg Chair of Design for the Carnegie Mellon School of Design. In 2011, he won the National Design Award for Interaction Design from the Cooper-Hewitt. With Casey Reas, Fry initiated Processing in 2001. - | -
-
- |
- - Daniel Shiffman works as an Associate Arts Professor at the Interactive Telecommunications Program at NYU's Tisch School of the Arts. Originally from Baltimore, Daniel received a BA in Mathematics and Philosophy from Yale University and a Master's Degree from the Interactive Telecommunications Program. He works on developing tutorials, examples, and libraries for Processing, the open source programming language and environment created by Casey Reas and Ben Fry. He is the author of Learning Processing: A Beginner's Guide to Programming Images, Animation, and Interaction and The Nature of Code (self-published via Kickstarter), an open source book about simulating natural phenomenon in Processing. - | -
-
- |
- - Lauren McCarthy is an artist based in Brooklyn, NY. She is full-time faculty at NYU ITP, and recently a resident at CMU STUDIO for Creative Inquiry and Eyebeam. She holds an MFA from UCLA and a BS Computer Science and BS Art and Design from MIT. Her work explores current systems and structures for being a person and interacting with other people. - | -
-
- |
- - Casey Reas is an artist and educator based in Los Angeles. He has exhibited, screened, and performed his work internationally in galleries and museums around the world. Reas is a professor at the University of California, Los Angeles. He holds a masters degree from the Massachusetts Institute of Technology in Media Arts and Sciences as well as a bachelors degree from the School of Design, Architecture, Art, and Planning at the University of Cincinnati. With Ben Fry, Reas initiated Processing in 2001. - | -
-
- |
- - Johanna Hedva is an artist and writer whose practice manifests in a wide range of projects, from performances of Ancient Greek plays rewritten to respond to feminist and queer political discourse, to poetry, novels, criticism, and theory. She's got an MA in Aesthetics and Politics, and an MFA in Art, from California Institute of the Arts, and has been an artist-in-residence at Headlands Center for the Arts, and writer-in-residence at the Armory Center for the Arts. Her work with the Processing Foundation is motivated by her political and social commitments to gender and racial diversity in technology and the arts; open-source philosophy and practice; and promoting the attenuation of the boundaries between creative and thought-making disciplines of all kinds. - | -
-
- |
- - John Maeda is currently a Design Partner at Kleiner Perkins Caufield & Byers. He was the President of the Rhode Island School of Design from 2008 to 2013, is a recipient of the National Design Award, and is represented in the permanent collection of the Museum of Modern Art. Beginning in 1996, lasting for 13 years, he was a Professor at MIT, where he served as an Associate Director of Research at the MIT Media Lab and was responsible for managing research relationships with 70+ industrial organizations. He received a Ph.D. in Design Science from the University of Tsukuba Institute of Art and Design in Japan. In May 2003, he received an Honorary Doctorate of Fine Arts from the Maryland Institute of Contemporary Art. He received an MBA from Arizona State University in May 2006. - | -
-
-
- Processing- -- Processing is a programming language, development environment, and online community. Founded in 2001, Processing was initially created to serve as a software sketchbook and to teach computer programming fundamentals within a visual context. Processing has since evolved into a development tool for professionals, an educational tool used in classrooms around the country, and a new context and medium for artists. Today, there are tens of thousands of students, artists, designers, researchers, and hobbyists who use Processing for learning, prototyping, and production. - - -- It was designed to be a user’s first programming language, inspired by earlier languages like BASIC and Logo, as well as our experiences as students and teaching visual arts foundation curricula. It is now used in classrooms worldwide, often in art schools and visual arts programs in universities, but also in high schools, computer science programs, and humanities curricula. - - -- In addition to educational purposes, the Processing software is used by thousands of visual designers, artists, and architects to create their works. Projects created with Processing have been featured at the Museum of Modern Art in New York, the Victoria and Albert Museum in London, the Centre Georges Pompidou in Paris, and many other prominent venues. Processing is used to create projected stage designs for dance and music performances; to generate images for music videos and film; to export images for posters, magazines, and books; and to create interactive installations in galleries, in museums, and on the street. - - -- - p5.js- -- p5.js is a JavaScript library that starts with the original goal of Processing--to make coding accessible for artists, designers, educators, and beginners--and reinterprets this for today's web. Using the original metaphor of a software sketchbook, p5.js has a full set of drawing functionality for the entire browser page. For this, p5.js has addon libraries that streamline interaction with other HTML5 objects, including text, input, video, webcam, and sound. - - -- Having just been released, p5.js is in active development, with an official editing environment and other features coming soon. - - -- - Processing.py- -- Our most recent initiative: To write Processing code. In Python. - - -- We are thrilled to make available this public release of the Python Mode for Processing, and its associated documentation. If you'd like to help us improve the implementation of Python Mode and its documentation, please find us on Github. - - - |
-
- -
-
- 2013 Report- -- We had a busy and productive 2013 with a wide range of activities: -
- - Google Summer of Code- -2014 Report- -- The Processing Foundation participated in Google Summer of Code for its fourth consecutive year in 2014, completing a total of eleven projects (summarized below) with a group of dedicated, innovative, and inspiring students. -
- 2013 Report- -- In 2013, our third year participating in Google Summer of Code, the Processing Foundation completed four projects in collaboration and mentorship with a group of talented students. -
|
-
- -
-
-
- Overview- -- The goal of the Processing Foundation is to promote software literacy, particularly within the visual arts, and to promote visual literacy within technology. Our primary charge is to develop and distribute the Processing software, both the core Application Programming Interface (API) and the programming environment, the Processing Development Environment (PDE). The board of directors for the Processing Foundation consists of Ben Fry, Casey Reas, and Dan Shiffman. The first member of the board of advisors is John Maeda. - - -- To succeed, the Foundation needs to raise money to support future versions of the Processing software and related initiatives. The Processing team, a small group of volunteers, has released over 200 versions of the software since 2001, leading to the 2.0 release in the spring of 2013.With almost no funding between the 1.0 and 2.0 releases, the software was written slowly while the developers managed full-time work and many other responsibilities. The 2.0 software release happened in an unsustainable way, at tremendous personal expense to the lead developers. The Foundation must raise funding for the initiative to continue. - - -- With the 2.0 software release, we're now asking for donations from individuals who use the software, and we're actively seeking larger gifts from individuals, companies, and other non-profit organizations. To learn more about why you might want to contribute, please read the 2013 status report below. The Processing Foundation was publicly announced in June 2013 with the release of the Processing 2.0 software. Our official non-profit status was was granted by the IRS on 6 March 2014, with our tax exception status retroactive to our date of formation, 14 June 2012. - - - - - -2013 Report- -- We had a busy and productive 2013 with a wide range of activities: -
- Despite the new fundraising goals, Processing remains almost entirely a volunteer organization pushed forward by a small group of people. In starting our fundraising push, the initial goal was to hire one full-time developer to maintain and build the Processing code base, while the current Processing team continues to volunteer time to the project. We've received a constant stream of donations through the Download page interface, but at the end of nine months the amount is about 10% of what we need to hire a developer. We're currently utilizing the donations to support Processing Fellows, short-term appointments to explore future directions for Processing and to produce essential libraries. For instance, we supported Lauren McCarthy to explore new ideas for integrating Processing with JavaScript and we supported Greg Borenstein to development the new OpenCV library. - - - - -Patrons- -- Individuals making $5 to $100 donations are the largest source of income for the Processing Foundation. We're grateful to all who have donated and we're proud to be supported by the community. - - -- In 2013, O'Reilly Media and Arduino made donations to the Processing Foundation. - - -- The Google Summer of Code program has provided and excellent source of energy and new development through supporting students to work with us. This program has now supported Processing for three years, 2010 to 2013. It has provided the base for many important enhancements to the software. - - -- Prior to incorporating as a Foundation, Processing received key funding and support from several organizations and companies. These commitments enabled a series of pivotal improvements to the software. - - -- The Interactive Telecommunications Program (ITP) at New York University sponsored a Processing 2.0 development workshop in the summer of 2011. - - -- The Armstrong Institute for Interactive Media Studies at Miami University funded The Oxford Project, a series of Processing development workshops during the 2008-2009 academic year. These four-day meetings in Oxford, Ohio, enabled the November 2008 launch of Processing 1.0 and stimulated future development. - - -- Oblong Industries funded Ben Fry to develop Processing during the summer of 2008. This funding also assisted in the completion of the 1.0 release. The Rockefeller Foundation awarded Ben Fry with a Media Arts Fellowship in 2006. The grant marked the first time that Ben was able to work on Processing as a funded project. This support led to further developments of the OpenGL and PDF rendering engines, as well as significant enhancements to other libraries and their integration. - - -- The Interaction Design Institute Ivrea funded four individuals' work on Processing in the summer of 2003. This resulted in Dan Mosedale's preprocessor using Antlr, Sami Arola's contributions to the graphics engine, and other contributions to the Processing Development Environment and 2D graphics engine. We are grateful to Interaction Ivrea director Gillian Crampton Smith for her encouragement and support. - - - |
-
@@ -28,7 +28,7 @@
- Interviews with SUE.C, Larry Cuba, Mark Hansen, Lynn Hershman Leeson, Jürg Lehni, LettError, Golan Levin and Zachary Lieberman, Benjamin Maus, Manfred Mohr, Ash Nehru, Josh On, Bob Sabiston, Jennifer Steinkamp, Jared Tarbell, Steph Thirion, and Robert Winter. + Interviews with SUE.C, Larry Cuba, Mark Hansen, Lynn Hershman Leeson, Jürg Lehni, LettError, Golan Levin and Zachary Lieberman, Benjamin Maus, Manfred Mohr, Ash Nehru, Josh On, Bob Sabiston, Jennifer Steinkamp, Jared Tarbell, Steph Thirion, and Robert Winter.
diff --git a/content/static/overview.html b/content/static/overview.html index 13349191d..d5d3d30ff 100644 --- a/content/static/overview.html +++ b/content/static/overview.html @@ -6,14 +6,11 @@- For the past fourteen years, Processing has promoted software literacy, particularly within the visual arts, and visual literacy within technology. Initially created to serve as a software sketchbook and to teach programming fundamentals within a visual context, Processing has also evolved into a development tool for professionals. The Processing software is free and open source, and runs on the Mac, Windows, and GNU/Linux platforms. - -
- Processing continues to be an alternative to proprietary software tools with restrictive and expensive licenses, making it accessible to schools and individual students. Its open source status encourages the community participation and collaboration that is vital to Processing’s growth. Contributors share programs, contribute code, and build libraries, tools, and modes to extend the possibilities of the software. The Processing community has written more than a hundred libraries to facilitate computer vision, data visualization, music composition, networking, 3D file exporting, and programming electronics. + For the past sixteen years, Processing has promoted software literacy, particularly within the visual arts, and visual literacy within technology. Initially created to serve as a software sketchbook and to teach programming fundamentals within a visual context, Processing has also evolved into a development tool for professionals. The Processing software is free and open source, and runs on the Mac, Windows, and GNU/Linux platforms.
- Processing is currently developed primarily in Boston (at Fathom Information Design), Los Angeles (at the UCLA Arts Software Studio), and New York City (at NYU’s ITP). + Processing continues to be an alternative to proprietary software tools with restrictive and expensive licenses, making it accessible to schools and individual students. Its open source status encourages the community participation and collaboration that is vital to Processing’s growth. Contributors share programs, contribute code, and build libraries, tools, and modes to extend the possibilities of the software. The Processing community has written more than a hundred libraries to facilitate computer vision, data visualization, music composition, networking, 3D file exporting, and programming electronics.
- The innovations in teaching through Processing have been adapted for the Khan Academy computer science tutorials, offered online for free. The tutorials begin with drawing, using most of the Processing functions for drawing. The Processing approach has also been applied to electronics through the Arduino and Wiring projects. Arduino uses a syntax inspired by that used with Processing, and continues to use a modified version of the Processing programming environment to make it easier for students to learn how to program robots and countless other electronics projects. + The innovations in teaching through Processing have been adapted for the Khan Academy computer science tutorials, offered online for free. The tutorials begin with drawing, using most of the Processing functions for drawing. The Processing approach has also been applied to electronics through the Arduino and Wiring projects. Arduino uses a syntax inspired by that used with Processing, and continues to use a modified version of the Processing programming environment to make it easier for students to learn how to program robots and countless other electronics projects.
-The primary charge of the Foundation is to develop and distribute the Processing software. This includes the original Processing (Java), p5.js (Javascript), and Processing.py (Python). There is more information about the Foundation at http://foundation.processing.org/. +The primary charge of the Foundation is to develop and distribute the Processing software. This includes the original Processing (Java), p5.js (Javascript), and Processing.py (Python). There is more information about the Foundation at https://processingfoundation.org/.
- Processing was started by Ben Fry and Casey Reas in the spring of 2001, while both were graduate students at the MIT Media Lab within John Maeda's Aesthetics and Computation research group. Development continued in their free time while Casey pursued his artistic and teaching career and Ben pursued a Ph.D. and founded Fathom Information Design. Many of the ideas in Processing go back to Muriel Cooper's Visual Language Workshop, and it grew directly out of Maeda's Design By Numbers project, developed at the Media Lab and released in 1999. The Wiring and Arduino projects, in turn, grew out of Processing while Casey was teaching at the Interaction Design Institute Ivrea in Italy. Processing also prompted John Resig (jQuery) to build Processing.js, a JavaScript version that then inspired more related work such as the Khan Academy curriculum in computer science. Versions of Processing that use Python, Ruby, ActionScript, and Scala are also in development. Processing and its sister projects have inspired over twenty educational books. + Processing was started by Ben Fry and Casey Reas in the spring of 2001, while both were graduate students at the MIT Media Lab within John Maeda's Aesthetics and Computation research group. Development continued in their free time while Casey pursued his art and teaching career and Ben pursued a Ph.D. and founded Fathom Information Design. Many of the ideas in Processing go back to Muriel Cooper's Visual Language Workshop, and it grew directly out of Maeda's Design By Numbers project, developed at the Media Lab and released in 1999. The Wiring and Arduino projects, in turn, grew out of Processing while Casey was teaching at the Interaction Design Institute Ivrea in Italy.
+For more information, please write to foundation@processing.org diff --git a/content/static/people.html b/content/static/people.html index ed14bc057..d406b648c 100755 --- a/content/static/people.html +++ b/content/static/people.html @@ -6,78 +6,57 @@
- Lead Developers
+ Project Leads
Ben Fry and Casey Reas
started Processing in Spring 2001 and continue to obsessively work on it. In 2012, they started the Processing Foundation along with Dan Shiffman, who formally joined as a third project lead.
- Senior Developers
- Andres Colubri (Boston), OpenGL / Video
- Florian Jenett (Frankfurt), Forum
- Elie Zananiri (Montreal), Contributed Libraries / Tools
- Scott Murray (San Francisco), Website / Reference / UI
+ Developers
+ Andres Colubri (Boston), OpenGL / Video
+ Elie Zananiri (New York), Contributed Libraries / Tools
+ Samuel Pottinger (San Francisco), Processing Core
+ -
+
Libraries, Tools
- The core Processing software is augmented by libraries and tools contributed through the community.
- These inventive extensions are a bright future for the project. We have a list of
- Contributed Libraries and
+ The core Processing software is augmented by libraries and tools contributed through
+ the community. These inventive extensions are a bright future for the project. We have a
+ list of Contributed Libraries and
Contributed Tools posted online.
- These contributions can't be underestimated. For example, see how
- Karsten Schmidt (London) has transformed Processing
- through the toxiclibs library and how
- Damien Di Fede (Austin) has extended the project
- into programming sound through his minim
- library.
-
- Fellowship Alumni
- Lauren McCarthy (New York), Spring/Summer/Fall 2013
- Greg Borenstein (New York), Spring/Summer 2013
- Wilm Thoben (Los Angeles), Fall 2013/Winter 2014
+ These contributions can't be underestimated. For example, see how Karsten Schmidt (London) has
+ transformed Processing through the toxiclibs library and how Damien Di Fede (Austin) has extended
+ the project into programming sound through his minim library.
- Developer Alumni
+ Alumni
+ Jakub Valtar (Brno), Processing Core
+ Scott Garner (New York), Hello Processing Website
+ Scott Murray (San Francisco), Website / Reference / UI
+ Gottfried Haider (Los Angeles), Processing for Pi
+ Florian Jenett (Frankfurt), Forum
+ Jamie Kosoy (San Francisco), Website
+ Manindra Moharana (San Diego), PDE / Core
+ James Grady (Boston), Visual Design
+
+
Patrick Hebron, Video Library (Summer 2011)
Peter Kalauskas, Library/Tool/Mode Install Utility (Summer, Fall 2011)
Andreas Schlegel, Libraries (Winter 2008 - Summer 2011)
Harshani Nawarathna, Processing Development Environment (Summer 2011)
Cindy Chi, Reference Editing (Summer 2011)
- Jonathan Feinberg, Parsing & Android Hacking (Spring 2011)
+ Jonathan Feinberg, Parsing & Android Hacking (Spring 2011)
Chris Lonnen, Processing Development Environment (Summer 2011)
Eric Jordan, Graphics Weapon (2007 - 2009)
Tom Carden, Processing Hacks Director (Summer 2005 - Fall 2008)
@@ -132,13 +111,9 @@
- -
-We offer a special "Thank You!" to Sami Arola for writing the base of the original P3D - and Simon Greenwold for incorporting camera and lights. Tom Carden contributed great + and Simon Greenwold for incorporating camera and lights. Tom Carden contributed great energy by co-creating Processing Hacks and maintaining Processing Blogs. Andreas Schlegel did amazing work for over three years organizing the Contributed Libraries and building templates and documentation. diff --git a/content/static/support.html b/content/static/support.html new file mode 100644 index 000000000..2a8f77f05 --- /dev/null +++ b/content/static/support.html @@ -0,0 +1,48 @@ + + +
Some helpful tips when you’re working with Processing & Android:
- I know I’ve said this before, but be patient. Canceling a process (ie. the emulator load or a device compile) can cause problems. If you do this inadvertently, you’re best off restarting Processing.
-- Make sure to check out the Processing Android Wiki, where you’ll find some troubleshooting advice, and some tips on how to get your sketches working properly on your device.
+- Make sure to check out the Processing Android Wiki, where you’ll find some troubleshooting advice, and some tips on how to get your sketches working properly on your device.
This tutorial is for Processing version 2.0+. If you see any errors or have comments, please let us know. This tutorial is adapted from 'Processing & Android: Mobile App Development Made (Very) Easy' by Jer Thorp
diff --git a/content/static/tutorials/arraylist/index.html b/content/static/tutorials/arraylist/index.html index 613ffee6a..5f24a6ad5 100644 --- a/content/static/tutorials/arraylist/index.html +++ b/content/static/tutorials/arraylist/index.html @@ -1,4 +1,4 @@ -In truth, we could use a simple array to manage our Particle objects. Some particle systems might have a fixed number of particles, and arrays are magnificently efficient in those instances. Processing also offers expand(), contract(), subset(), splice() and other methods for resizing arrays. However, for these examples, the Java class ArrayList (found in the java.util package: http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html) will prove to be the best solution. Using an ArrayList is conceptually similar to a standard array, but the syntax is different. Here is some code (that assumes the existence of a generic Particle class) demonstrating identical results: first with an array, and second with an ArrayList. +In truth, we could use a simple array to manage our Particle objects. Some particle systems might have a fixed number of particles, and arrays are magnificently efficient in those instances. Processing also offers expand(), contract(), subset(), splice() and other methods for resizing arrays. However, for these examples, the Java class ArrayList (found in the java.util package: https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html) will prove to be the best solution. Using an ArrayList is conceptually similar to a standard array, but the syntax is different. Here is some code (that assumes the existence of a generic Particle class) demonstrating identical results: first with an array, and second with an ArrayList. // THE STANDARD ARRAY WAY int total = 10; diff --git a/content/static/tutorials/data/imgs/data_03_table.png b/content/static/tutorials/data/imgs/data_03_table.png index d0ff43b2d..961ac434c 100644 Binary files a/content/static/tutorials/data/imgs/data_03_table.png and b/content/static/tutorials/data/imgs/data_03_table.png differ diff --git a/content/static/tutorials/data/imgs/data_04_excel.jpg b/content/static/tutorials/data/imgs/data_04_excel.jpg index 1406af987..c004098da 100755 Binary files a/content/static/tutorials/data/imgs/data_04_excel.jpg and b/content/static/tutorials/data/imgs/data_04_excel.jpg differ diff --git a/content/static/tutorials/data/imgs/data_06_xml.jpg b/content/static/tutorials/data/imgs/data_06_xml.jpg index 7a1a18035..10cadd588 100755 Binary files a/content/static/tutorials/data/imgs/data_06_xml.jpg and b/content/static/tutorials/data/imgs/data_06_xml.jpg differ diff --git a/content/static/tutorials/data/imgs/data_07_weatherxml.jpg b/content/static/tutorials/data/imgs/data_07_weatherxml.jpg index bc65c1042..e0de2e503 100755 Binary files a/content/static/tutorials/data/imgs/data_07_weatherxml.jpg and b/content/static/tutorials/data/imgs/data_07_weatherxml.jpg differ diff --git a/content/static/tutorials/data/imgs/fig_18_01_user_input.png b/content/static/tutorials/data/imgs/fig_18_01_user_input.png new file mode 100755 index 000000000..e4b8f4797 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_01_user_input.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_02_filetxt.png b/content/static/tutorials/data/imgs/fig_18_02_filetxt.png new file mode 100755 index 000000000..2e82a2f1d Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_02_filetxt.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_03_datatxt.png b/content/static/tutorials/data/imgs/fig_18_03_datatxt.png new file mode 100755 index 000000000..33a877bcb Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_03_datatxt.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_04_bargraph.png b/content/static/tutorials/data/imgs/fig_18_04_bargraph.png new file mode 100755 index 000000000..ef797f982 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_04_bargraph.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_05_datacsv.png b/content/static/tutorials/data/imgs/fig_18_05_datacsv.png new file mode 100755 index 000000000..6c75a3c9c Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_05_datacsv.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_06_datacsv_grid.png b/content/static/tutorials/data/imgs/fig_18_06_datacsv_grid.png new file mode 100755 index 000000000..77de335e7 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_06_datacsv_grid.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_07_tablebubbles.png b/content/static/tutorials/data/imgs/fig_18_07_tablebubbles.png new file mode 100755 index 000000000..64a8e5f79 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_07_tablebubbles.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_08_rollover.png b/content/static/tutorials/data/imgs/fig_18_08_rollover.png new file mode 100644 index 000000000..7b823a954 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_08_rollover.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_09_shaunsheep.png b/content/static/tutorials/data/imgs/fig_18_09_shaunsheep.png new file mode 100755 index 000000000..8d5398cf2 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_09_shaunsheep.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_10_shaunsheep_sourc.png b/content/static/tutorials/data/imgs/fig_18_10_shaunsheep_sourc.png new file mode 100755 index 000000000..b4456ba92 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_10_shaunsheep_sourc.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_11_parsing_imdb.png b/content/static/tutorials/data/imgs/fig_18_11_parsing_imdb.png new file mode 100755 index 000000000..61acef65d Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_11_parsing_imdb.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_12_traditional_arra.png b/content/static/tutorials/data/imgs/fig_18_12_traditional_arra.png new file mode 100644 index 000000000..402f9e213 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_12_traditional_arra.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_13_associative_arra.png b/content/static/tutorials/data/imgs/fig_18_13_associative_arra.png new file mode 100644 index 000000000..82fe0b68f Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_13_associative_arra.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_14_concordance_viz.png b/content/static/tutorials/data/imgs/fig_18_14_concordance_viz.png new file mode 100755 index 000000000..f60db5375 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_14_concordance_viz.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_15_xml_tree.png b/content/static/tutorials/data/imgs/fig_18_15_xml_tree.png new file mode 100755 index 000000000..8535f1b6e Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_15_xml_tree.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_16_rss.png b/content/static/tutorials/data/imgs/fig_18_16_rss.png new file mode 100755 index 000000000..1bdb2d482 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_16_rss.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_17_weather.png b/content/static/tutorials/data/imgs/fig_18_17_weather.png new file mode 100755 index 000000000..f379ab30f Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_17_weather.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_18_xmlbubbles.png b/content/static/tutorials/data/imgs/fig_18_18_xmlbubbles.png new file mode 100755 index 000000000..b58ced2a2 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_18_xmlbubbles.png differ diff --git a/content/static/tutorials/data/imgs/fig_18_19_thread.png b/content/static/tutorials/data/imgs/fig_18_19_thread.png new file mode 100755 index 000000000..f79c43d28 Binary files /dev/null and b/content/static/tutorials/data/imgs/fig_18_19_thread.png differ diff --git a/content/static/tutorials/data/index-old.html b/content/static/tutorials/data/index-old.html new file mode 100644 index 000000000..6221a4a80 --- /dev/null +++ b/content/static/tutorials/data/index-old.html @@ -0,0 +1,527 @@ +|
+
+ + This tutorial is from the book Learning Processing by Daniel Shiffman, published by Morgan Kaufmann, © 2008 Elsevier Inc. All rights reserved. If you see any errors or have comments, please let us know. + + +Data+Daniel Shiffman+ + ++ This tutorial picks up where the Strings and Drawing Text tutorial leaves off and examines how to use String objects as the basis for reading and writing data. We'll start by learning more sophisticated methods for manipulating Strings, searching in them, chopping them up, and joining them together. Afterwards, we'll see how these skills allow us to use input from data sources, such as text files, web pages, xml feeds, and 3rd party APIs and take a step into the world of data visualization. + + +Manipulating Strings+ ++ In Strings and Drawing Text, we touched on a few of the basic functions available in the Java String class, such as charAt(), toUpperCase(), equals(), and length(). These functions are documented on the Processing reference page for Strings. Nevertheless, in order to perform some more advanced data parsing techniques, we'll need to explore some additional String manipulation functions documented in the Java API. + + ++ Let's take a closer look at the following two String functions: indexOf() and substring(). indexOf() locates a sequence of characters within a String. It takes one argument, a search String, and returns a numeric value that corresponds to first occurrence of the search string inside of the string being searched. + + ++String search = "def"; +String toBeSearched = "abcdefghi"; +int index = toBeSearched.indexOf(search); // The value of index in this example is 3. ++ + + Strings are just like arrays, in that the first character is index number zero and the last character is the length of the string minus one. If the search string cannot be found, indexOf() returns -1. This is a good choice because -1 is not a legitimate index value and therefore can indicate "not found." After finding a search phrase within a String, we might want to separate out part of the string, saving it in a different variable. A part of a string is known as "substring." The substring() function which takes two arguments, a start index and an end index and returns the substring in between the two indices. + + ++String alphabet = "abcdefghi"; +String sub = alphabet.substring(3,6); // The String sub is now "def". ++ + Note that the substring begins at the specified start index (the first argument) and extends to the character at end index (the second argument) minus one. I know. I know. Wouldn't it have been easier to just take the substring from the start index all the way to the end index? While this might initially seem true, it's actually quite convenient to stop at end index minus one. For example, if you ever want to make a substring that extends to the end of a string, you can simply go all the way to thestring.length(). In addition, with end index minus one marking the end, the length of the substring is easily calculated as end index minus begin index. + +Splitting and Joining Strings+ +In Strings and Drawing Text, we saw how strings can be joined together (referred to as "concatenation") using the "+" operator. Let's review with a example that uses concatenation to get user input from a keyboard. Processing has two additional functions that make joining strings (or the reverse, splitting them up) easy. In sketches that involve parsing data from a file or the web, we will often be presented that data in the form of an array of strings or as one long string. Depending on what we want to accomplish, it's useful to know how to switch between these two modes of storage. This is where these two new functions, split() and join(), will come in handy. + +"one long string or array of strings" ←→ {"one", "long", "string", "or" ,"array", "of", "strings"} + +Let's take a look at the split() function. split() separates a longer string into an array of strings, based on a split character known as the delimiter. It takes two arguments, the string to be split and the delimiter. (The delimiter can be a single character or a string. Note that in the code below the period is not set as a delimiter and therefore will be included in the last string in the array: "dog." + +
+// Splitting a String based on spaces
+String spaceswords = "The quick brown fox jumps over the lazy dog.";
+String[] list = split(spaceswords, " ");
+for (int i = 0; i < list.length; i++) {
+ println(list[i] + " " + i);
+}
+
+
+If you want to use more than one delimiter to split up a text, you must use the Processing function splitTokens(). splitTokens() works identically to split() with one exception: any character that appears in the String qualifies as a delimiter. In the code below, the period is set as a delimiter and therefore will not be included in the last spot in the array: "dog" + +
+// Splitting a String based on a multiple delimiters
+String stuff = "hats & apples, cars + phones % elephants dog.";
+String[] list = splitTokens(stuff, " &,+.");
+for (int i = 0; i < list.length; i++) {
+ println(list[i] + " " + i);
+}
+
+
+If we are splitting numbers in a String the resulting array can be converted into an integer array with Processing's int() function. Numbers in a string are not numbers and cannot be used in mathematical operations unless we convert them first. + +
+// Calculate sum of a list of numbers in a String
+String numbers = "8,67,5,309";
+// Converting the String array to an int array
+int[] list = int(split(numbers, ','));
+int sum = 0;
+for (int i = 0; i < list.length; i++) {
+ sum = sum + list[i];
+}
+println(sum);
+
+
+The reverse of split() is join(). join() takes an array of Strings and joins them together into one long string. The join() function also takes two arguments, the array to be joined and a separator. The separator can either be a single character or a String of characters. + +Consider the following array: + +
+String[] lines = {"It", "was", "a", "dark", "and", "stormy", "night."};
+
+
+Using the + operator along with a for loop, we can join an array of strings together as follows: + +
+// Manual Concatenation
+String onelongstring = "";
+for (int i = 0; i < lines.length; i++) {
+ onelongstring = onelongstring + lines[i] + " ";
+}
+
+
+The join() function, however, allows us to bypass this process achieving the same result in only one line of code. + ++// Using Processing's join() +String onelongstring = join(lines," "); ++ + Reading and Writing Text Files+ +Data can come from many different places: web sites, news feeds, databases, etc. To start, we'll demonstrate how to work with the simplest means of data retrieval data: reading from a text file.Text files can be used as a very simple database (we could store settings for a program, a list of high scores, numbers for a graph, etc.) or to simulate a more complex data source. + +In order to create a text file, you can use any simple text editor. Windows Notepad or Mac OSX TextEdit will do, just make sure you format the file as "plain text." It is also advisable to name the text files with the ".txt" extension, just to avoid any confusion. And just as with image files, these text files should be placed in the sketch's "data" directory in order for them to be recognized by the Processing sketch. + +Once the text file is in place, Processing's loadStrings() function is used to read the content of the file into an String array. The individual lines of text in the file each become an individual element in the array. + +
+
+
+// This code will print all the lines from the source text file.
+String[] lines = loadStrings("file.txt");
+println("there are " + lines.length + " lines");
+println(lines);
+
+
+Text from a file can be used to generate a simple visualization. Take the following data file. + +
+
+Here, we can load the numbers separated by commas and split them into an array of ints used to set color and height of rectangles. + +
+int[] data;
+
+void setup() {
+ size(200,200);
+ // Load text file as a string
+ String[] stuff = loadStrings("data.txt");
+ // Convert string into an array of integers using ',' as a delimiter
+ data = int(split(stuff[0],','));
+}
+
+void draw() {
+ background(255);
+ stroke(0);
+ for (int i = 0; i < data.length; i++) {
+ fill(data[i]);
+ rect(i*20,0,20,data[i]);
+ }
+}
+
+
+Text can also be written back to a data file with saveStrings(). saveStrings() writes an array of strings to a file, one line per string. + +
+String words = "apple bear cat dog";
+String[] list = split(words, ' ');
+
+// Writes the strings to a file, each on a separate line
+saveStrings("nouns.txt", list);
+
+
+There are cases, however, where you don't want to write a text file all at once. Rather, you want to continuously append to a file over time. This can be achieved with the PrintWriter class. Take the following example which writes saves mouseX and mouseY to a text file for each cycle through draw(), quitting when you press a key. + +
+PrintWriter output;
+
+void setup() {
+ // Create a new file in the sketch directory
+ output = createWriter("positions.txt");
+}
+
+void draw() {
+ point(mouseX, mouseY);
+ output.println(mouseX); // Write the coordinate to the file
+}
+
+void keyPressed() {
+ output.flush(); // Writes the remaining data to the file
+ output.close(); // Finishes the file
+ exit(); // Stops the program
+}
+
+
+Tabular Data+ +You may have noticed that the graphing example above loads a text file with numbers separated by commas. Processing includes a Table class which will load a comma-separated (CSV) or tab-separated (TSV) file and automatically parse the data into columns and rows for you. This is a great deal more convenient than struggling to manually parse large data files with split(). It works as follows. Let's say you have a data file that looks like: + +
+
+Instead of saying: + +
+String[] stuff = loadStrings("data.csv");
+
+
+We can now say: + +
+Table table = loadTable("data.csv");
+
+
+Now we've missed an important detail. Take a look at the data.csv text file above. Notice how the first line of text is not the data itself, but rather a "header row." This row includes labels that describe the data included in each subsequent row. The good news is that Processing can automatically interpret and store the headers for you, if you pass in the option "header" when loading the table. (In addition to "header" there are other options you can specify. For example if your file is called data.txt but is comma separated data you can pass in the option "csv". If it also has a header row, then you can specifiy both options like so: "header,csv"). A full list of options can be found on the loadTable() documentation page. + +
+Table table = loadTable("data.csv","header");
+
+
+Now that the table is loaded, we can look at how we grab individual pieces of data or iterate over the entire table. Let's look at the data visualized as a grid. + +
+
+In the above grid we can see that the data is organized in terms of rows and columns. One way to access the data would be to therefore request a value by its numeric row and column location (with zero being the first row or first column). This is similar to accessing a pixel color at a given (x, y) location though in this case the y position (i.e. row) comes first. The following code requests a piece of data at a given (row, column) location. + ++int val1 = table.getInt(2, 1); // val now has the value 235 +float val2 = table.getFloat(3, 2); // val2 now has the value 44.758068 +String s = table.getString(0, 3); // s now has the value "Happy" ++ + While the numeric index is sometimes useful, it's generally going to be more convenient to access each piece of data by the column name. For example, we could pull out a specific row from the Table. + ++TableRow row = table.getRow(2); // Gets the third row (index 2) ++ +Note in the above line of code that a Table object refers to the entire table of data while a TableRow object handles an individual row of data within the Table. + +Once we have the TableRow object, we can ask for data from some or all of the columns. + +
+int x = row.getInt("x"); // x has the value 273
+int y = row.getInt("y"); // y has the value 235
+float d = row.getFloat("diameter"); // d has the value 61.14072
+String s = row.getString("name"); // s has the value "Joyous"
+
+
+The method getRow() returns a single row from the table. If you want to grab all the rows and iterate over them you can do so with the method rows().
+
+
+for (TableRow row : table.rows()) {
+ float x = row.getFloat("x");
+ float y = row.getFloat("y");
+ float d = row.getFloat("diameter");
+ String n = row.getString("name");
+ // Do something with the data of each row
+}
+
+
+If you want to search for a select number of rows within the table, you can do so with findRows() and matchRows().
+
+In addition to being read, Table objects can be altered or created on the fly while a sketch is running. Cell values can be adjusted, rows can be removed, and new rows can be added. For example, to set new values in a cell there are functions setInt(), setFloat(), and setString(). + +
+// Update the value of column "x" to mouseX in a given TableRow.
+row.setInt("x",mouseX);
+
+
+To add a new row to a Table, simply call the method addRow() and set the values of each column. + +
+// Create a new row
+TableRow row = table.addRow();
+// Set the values of that row
+row.setFloat("x", mouseX);
+row.setFloat("y", mouseY);
+row.setFloat("diameter", random(40, 80));
+row.setString("name", "new label");
+
+
+To delete a row to a Table, simply call the method removeRow() and pass in the numeric index of the row you would like removed. The following code for example, removes the first row whenever the size of the table is greater than ten rows. + +
+// If the table has more than 10 rows
+if (table.getRowCount() > 10) {
+ // Delete the first row
+ table.removeRow(0);
+}
+
+
+For an example that creates objects from and saves objects to a Table, take a look at LoadSaveTable under Topics --> Advanced Data. + +XML Data+ +For grabbing data from the web, an XML (Extensible Markup Language) feed is an excellent option (if available). Unlike HTML (which is designed to make content vieweable by a human's eyes) XML is designed to make content viewable by a computer and facilitate the sharing of data across different systems. + +XML organizes information in a tree structure. Let's imagine a list of students. Each student has an id number, name, address, e-mail, and telephone number. Each student's address has a city, state, and zip code. An XML tree for this dataset might look like the following: + +
+<?xml version="1.0" encoding="UTF-8"?> +<students> + <student> + <id>001</id> + <name>Daniel Shiffman</name> + <phone>555-555-5555</phone> + <email>daniel@shiffman.net</email> + <address> + <street>123 Processing Way</street> + <city>Loops</city> + <state>New York</state> + <zip>01234</zip> + </address> + </student> + <student> + <id>002</id> + <name>Zoog</name> + <phone>555-555-5555</phone> + <email>zoog@planetzoron.uni</email> + <address> + <street>45.3 Nebula 5</street> + <city>Boolean City</city> + <state&tt;Booles</state> + <zip>12358</zip> + </address> + </student> +</students> ++ + Note the similarities to object-oriented programming. We could think of the XML tree in the following terms. The XML document represents an array of student objects. Each student object has multiple pieces of information, an id, a name, a phone number, an e-mail address, and a mailing address. The mailing address is also an object that also has multiple pieces of data, such as street, city, state, and zip. + +Let's look at Yahoo's XML feed for weather data. Here is the raw XML source (Note I have edited it for simplification purposes). + ++<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"> + <channel> + <item> + <title>Conditions for New York, NY at 3:51 pm EST</title> + <geo:lat>40.67</geo:lat> + <geo:long>-73.94</geo:long> + <link>http://xml.weather.yahoo.com/forecast/USNY0996_f.html</link> + <pubDate>Mon, 20 Feb 2006 3:51 pm EST</pubDate> + <yweather:condition text="Fair" code="34" temp="35" date="Mon, 20 Feb 2006 3:51 pm EST"/> + <yweather:forecast day="Mon" date="20 Feb 2006" low="25" high="37" text="Clear" code="31"/> + </item> + </channel> +</rss> ++ + And here is the data mapped in the tree structure. + +
You may be wondering what the top level "RSS" is all about. Yahoo's XML weather data is provided in RSS format. RSS stands for "Really Simple Syndication" and is a standardized XML format for syndicating web content (such as news articles, etc.) + +Now that we have a handle on the tree structure, we should look at the specifics inside that structure. With the exception of the first line (which simply indicates that this page is XML formatted), this XML document contains a nested list of elements, each with a start tag, i.e. <channel> and an end tag, i.e. </channel>. Some of these elements have content between the tags: + ++<title>Conditions for New York, NY at 3:51 pm EST</title> ++ + and some have attributes (formatted by attribute name equals attribute value in quotes): + ++<yweather:condition text="Fair" code="34" temp="35" date="Mon, 20 Feb 2006 3:51 pm EST"/> ++ + Knowing this format, we could certainly be clever with our use of split(), indexOf(), and substring() to find the pieces we want in the raw XML. The point here, however, is that because XML is a standard format, we don't have to do this. Rather, we can use an XML parser. In Processing, the XML parser is called just that: XML. + +
+XML xml = loadXML("http://xml.weather.yahoo.com/forecastrss?p=10003");
+
+
+Here, instead of loadStrings() or loadTable(), we're now calling loadXML() and passing in the address (URL or local file) of our XML document. An XML object represents one element of an XML tree. When a document is first loaded, that XML object is always the root element. Referring back to XML tree diagram, we see that we can find the current temperature via the following path: + +
We could translate the above into code as follows: + +
+XML root = loadXML("http://xml.weather.yahoo.com/forecastrss?p=10003"); // Step 1
+XML channel = root.getChild("channel"); // Step 2
+XML item = channel.getChild("item"); // Step 3
+XML yweather = item.getChild("yweather:condition"); // Step 4
+int temperature = yweather.getInt("temp"); // Step 5
+
+
+This is a bit long-winded, however, and so can be compressed down into one (or three as below) lines of code. + +
+XML root = loadXML(http://xml.weather.yahoo.com/forecastrss?p=10003); // Step 1
+XML forecast = root.getChild("channel").getChild("item").getChild("yweather:condition"); // Steps 2-4
+int temperature = forecast.getInt("temp"); // Step 5
+
+
+Finally, the second line of code above can be further condensed to:
+
+
+XML forecast = xml.getChild("channel/item/yweather:condition"); // Steps 2-4
+
+
+It should also be noted that we're accessing the child nodes by their name (i.e. "channel", "item", etc.), but they can also be accessed numerically via an index (starting at zero, same as an array). This is convenient when looping over a list of children. In LoadSaveTable, we used a series of comma separated values in a text file to store information related to Bubble objects. An XML document can also be used in the same manner. Consider the following XML document: + ++<?xml version="1.0" encoding="UTF-8"?> +<bubbles> + <bubble> + <position x="160" y="103"/> + <diameter>43.19838</diameter> + <label>Happy</label> + </bubble> + <bubble> + <position x="372" y="137"/> + <diameter>52.42526</diameter> + <label>Sad</label> + </bubble> + <bubble> + <position x="273" y="235"/> + <diameter>61.14072</diameter> + <label>Joyous</label> + </bubble> + <bubble> + <position x="121" y="179"/> + <diameter>44.758068</diameter> + <label>Melancholy</label> + </bubble> +</bubbles> ++ + In the above XML, the root element is "bubbles" which has four children. Each child "bubble" has 3 children, "position", "diameter", and "label." The "position" element has two attributes, "x" and "y." To access the list of all XML nodes "bubble" we can use the getChildren() method, passing in the name "bubble" + +
+// Load an XML document
+XML xml = loadXML("bubbles.xml");
+
+// Get all the child elements
+XML[] children = xml.getChildren("bubble");
+
+
+Once we have the array of XML objects, we can iterate over them, accessing the individual pieces of data for each "bubble". Notice how the syntax for getting XML attributes (in this case, "x" and "y" of the position element is slightly different than pulling content directly from an element (in this case, "diameter" and "label"). + +
+for (int i = 0; i < bubbles.length; i++) {
+
+ // The position element has two attributes: x and y
+ XML positionElement = children[i].getChild("position");
+ // Note how with attributes we can get an integer or float via getInt() and getFloat()
+ float x = positionElement.getInt("x");
+ float y = positionElement.getInt("y");
+
+ // The diameter is the content of the child named "diamater"
+ XML diameterElement = children[i].getChild("diameter");
+ // Note how with the content of an XML node, we retrieve via getIntContent() and getFloatContent()
+ float diameter = diameterElement.getFloatContent();
+
+ // The label is the content of the child named "label"
+ XML labelElement = children[i].getChild("label");
+ String label = labelElement.getContent();
+}
+
+
+XML elements can be added and removed from the XML tree with the addChild() and removeChild() methods. + +For the full example that creates objects from and saves objects to an XML document, take a look at LoadSaveXML under Topics --> Advanced Data. + +Threads+ +You are likely familiar with the idea of writing a program that follows a specific sequence of steps -- setup() first then draw() over and over and over again! A Thread is also a series of steps with a beginning, a middle, and an end. A Processing sketch is a single thread, often referred to as the "Animation" thread. Other threads sequences, however, can run independently of the main Processing sketch. In fact, you can launch any number of threads at one time and they will all run concurrently. + +Processing does this all the time, whenever you write an event callback, such as serialEvent(), or captureEvent(), etc. these functions are triggered by a different thread running behind the scenes, and they alert Processing whenever they have something to report. This is useful whenever you need to perform a task that takes too long and would slow down the main animation's frame rate, such as grabbing data from the network (XML, database, etc.) If a separate thread gets stuck or has an error, the entire program won't grind to a halt, since the error only stops that individual thread. To create independent, asynchronous threads, you can use the thread() function built into Processing. + +
+void setup() {
+ size(200,200);
+ thread("someFunction");
+}
+
+void draw() {
+
+}
+
+void someFunction() {
+ // This function will run as a thread when called via
+ // thread("someFunction") as it was in setup!
+}
+
+
+The thread() function receives a String as an argument. The String should match the name of the function you want to run as a thread. This is especially useful in sketches that grab data for the web. Rather than have the animation freeze while the sketch is waiting to retrieve data, the sketch can continue to loop through draw() updating the data when the thread is completed. In these cases, a boolean variable can be useful to track the status of the thread. + ++boolean loading = false; ++ + The function that loads the data can then set loading equal to true at the start and false at the end. + +
+void loadData() {
+ loading = true;
+
+ ///////////////////////////////////
+ // All of the data retrival code //
+ ///////////////////////////////////
+
+ loading = false;
+}
+
+
+In draw(), you can choose to display something to indicate the thread is running (when loading equals true). + +
+void draw() {
+ if (loading) {
+ // Draw something to indicate loading
+ }
+}
+
+
+
+Two examples that follow this methodology can be found under Topics --> Advanced Data in the Processing examples. + +While using the thread() function is a very simple way of getting an independent thread, it should be noted that it is somewhat limited. Being able to make a thread object is a great deal more powerful, and this can be done by extending the Java Thread class. + + + |
+
- This tutorial is from the book Learning Processing by Daniel Shiffman, published by Morgan Kaufmann, © 2008 Elsevier Inc. All rights reserved. If you see any errors or have comments, please let us know. + This tutorial is from the book Learning Processing, 2nd Edition by Daniel Shiffman, published by Morgan Kaufmann, © 2015 Elsevier Inc. All rights reserved. If you see any errors or have comments, please let us know.
- In Strings and Drawing Text, we touched on a few of the basic functions available in the Java String class, such as charAt(), toUpperCase(), equals(), and length(). These functions are documented on the Processing reference page for Strings. Nevertheless, in order to perform some more advanced data parsing techniques, we'll need to explore some additional String manipulation functions documented in the Java API. -
- -- Let's take a closer look at the following two String functions: indexOf() and substring(). indexOf() locates a sequence of characters within a String. It takes one argument, a search String, and returns a numeric value that corresponds to first occurrence of the search string inside of the string being searched. -
- + In Strings and Drawing Text, we touched on a few of the basic functions available in the Java String, such as charAt(), toUpperCase(), equals(), and length(). These functions are documented on the Processing reference page for Strings. Nevertheless, in order to perform some more advanced data parsing techniques, we'll need to explore some additional String manipulation functions documented in the Java API. +String search = "def"; String toBeSearched = "abcdefghi"; int index = toBeSearched.indexOf(search); // The value of index in this example is 3.-
- Strings are just like arrays, in that the first character is index number zero and the last character is the length of the string minus one. If the search string cannot be found, indexOf() returns -1. This is a good choice because -1 is not a legitimate index value and therefore can indicate "not found." After finding a search phrase within a String, we might want to separate out part of the string, saving it in a different variable. A part of a string is known as "substring." The substring() function which takes two arguments, a start index and an end index and returns the substring in between the two indices. -
- + Strings are just like arrays, in that the first character is index number zero and the last character is the length of the string minus one. If the search string cannot be found, indexOf() returns -1. This is a good choice because -1 is not a legitimate index value in the string itself, and therefore can indicate "not found." There are no negative indices in a string of characters or in an array. +String alphabet = "abcdefghi"; -String sub = alphabet.substring(3,6); // The String sub is now "def". +String sub = alphabet.substring(3, 6); // The String sub is now "def".- -
Note that the substring begins at the specified start index (the first argument) and extends to the character at end index (the second argument) minus one. I know. I know. Wouldn't it have been easier to just take the substring from the start index all the way to the end index? While this might initially seem true, it's actually quite convenient to stop at end index minus one. For example, if you ever want to make a substring that extends to the end of a string, you can simply go all the way to thestring.length(). In addition, with end index minus one marking the end, the length of the substring is easily calculated as end index minus begin index.
+ Note that the substring begins at the specified start index (the first argument) and extends to the character at end index (the second argument) minus one. I know, I know. Wouldn’t it have been easier to just take the substring from the start index all the way to the end index? While this might initially seem true, it’s actually quite convenient to stop at end index minus one. For example, if you ever want to make a substring that extends to the end of a string, you can simply go all the way to thestring.length(). In addition, with end index minus one marking the end, the length of the substring is easily calculated as end index minus begin index. +In Strings and Drawing Text, we saw how strings can be joined together (referred to as "concatenation") using the "+" operator. Let's review with a example that uses concatenation to get user input from a keyboard. Processing has two additional functions that make joining strings (or the reverse, splitting them up) easy. In sketches that involve parsing data from a file or the web, we will often be presented that data in the form of an array of strings or as one long string. Depending on what we want to accomplish, it's useful to know how to switch between these two modes of storage. This is where these two new functions, split() and join(), will come in handy.
- -"one long string or array of strings" ←→ {"one", "long", "string", "or" ,"array", "of", "strings"} - -Let's take a look at the split() function. split() separates a longer string into an array of strings, based on a split character known as the delimiter. It takes two arguments, the string to be split and the delimiter. (The delimiter can be a single character or a string. Note that in the code below the period is not set as a delimiter and therefore will be included in the last string in the array: "dog."
- +
+ In Strings and Drawing Text, we saw how strings can be joined together (referred to as "concatenation") using the "+" operator. Let's review with a example that uses concatenation to get user input from a keyboard.
+
+
+
+PFont f;
+
+// Variable to store text currently being typed
+String typing = "";
+// Variable to store saved text when return is hit
+String saved = "";
+
+void setup() {
+ size(300, 200);
+ f = createFont("Arial", 16);
+}
+
+void draw() {
+ background(255);
+ int indent = 25;
+
+ // Set the font and fill for text
+ textFont(f);
+ fill(0);
+
+ // Display everything
+ text("Click in this sketch and type. \nHit return to save what you typed.", indent, 40);
+ text(typing, indent, 90);
+ text(saved, indent, 130);
+}
+
+void keyPressed() {
+ // If the return key is pressed, save the String and clear it
+ if (key == '\n') {
+ saved = typing;
+ typing = "";
+ // Otherwise, concatenate the String
+ } else {
+ typing = typing + key;
+ }
+}
+
+ Processing has two additional functions that make joining strings (or the reverse, splitting them up) easy. In sketches that involve parsing data from a file or the web, you might get hold of that data in the form of an array of strings or as one long string. Depending on what you want to accomplish, it’s useful to know how to switch between these two modes of storage. This is where these two new functions, split() and join(), will come in handy.
+
+
+ "one long string or array of strings" ←→ {"one", "long", "string", "or" ,"array", "of", "strings"}
+
+
+ Let’s take a look at the split() function. split() separates a longer string into an array of strings, based on a split character known as the delimiter. It takes two arguments, the String object to be split and the delimiter. (The delimiter can be a single character or a string.) In the code below, the period is not set as a delimiter and therefore will be included in the last string in the array: “dog.” Note how printArray() can be used to print the contents of an array and their corresponding indices to the message console.
-// Splitting a String based on spaces
+// Splitting a string based on spaces
String spaceswords = "The quick brown fox jumps over the lazy dog.";
String[] list = split(spaceswords, " ");
-for (int i = 0; i < list.length; i++) {
- println(list[i] + " " + i);
-}
+printArray(list);
-
-If you want to use more than one delimiter to split up a text, you must use the Processing function splitTokens(). splitTokens() works identically to split() with one exception: any character that appears in the String qualifies as a delimiter. In the code below, the period is set as a delimiter and therefore will not be included in the last spot in the array: "dog"
- + Here is an example using a comma as the delimiter (this time passing in a single character: ','.) +
-// Splitting a String based on a multiple delimiters
-String stuff = "hats & apples, cars + phones % elephants dog.";
-String[] list = splitTokens(stuff, " &,+.");
-for (int i = 0; i < list.length; i++) {
- println(list[i] + " " + i);
-}
+// Splitting a string based on commas
+String commaswords = "The,quick,brown,fox,jumps,over,the,lazy,dog.";
+String[] list = split(commaswords, ",");
+printArray(list);
-
-If we are splitting numbers in a String the resulting array can be converted into an integer array with Processing's int() function. Numbers in a string are not numbers and cannot be used in mathematical operations unless we convert them first.
- + If you want to use more than one delimiter to split up a text, you must use the Processing function splitTokens(). splitTokens() works identically as split() with one exception: any character that appears in the passed string qualifies as a delimiter.) In the code below, the period is specified as a delimiter and therefore will not be included in the last string in the array: “dog”.+// Splitting a String based on multiple delimiters +String stuff = "hats & apples, cars + phones % elephants dog."; +String[] list = splitTokens(stuff, " &,+." ); +printArray(list); ++ If you are splitting numbers in a string, the resulting array can be converted into an integer array with Processing’s int() function. Numbers in a string are not numbers and cannot be used in mathematical operations unless you convert them first.
// Calculate sum of a list of numbers in a String
String numbers = "8,67,5,309";
// Converting the String array to an int array
-int[] list = int(split(numbers, ','));
+int[] list = int(split(numbers, ','));
int sum = 0;
-for (int i = 0; i < list.length; i++) {
+for (int i = 0; i<list.length; i++ ) {
sum = sum + list[i];
}
-println(sum);
+println(sum);
-
-The reverse of split() is join(). join() takes an array of Strings and joins them together into one long string. The join() function also takes two arguments, the array to be joined and a separator. The separator can either be a single character or a String of characters.
- -Consider the following array:
- + The reverse of split() is join(). join() takes an array of strings and joins them together into one long String object. The join() function also takes two arguments, the array to be joined and a separator. The separator can either be a single character or a string of characters. + + +
+ Consider the following array:
String[] lines = {"It", "was", "a", "dark", "and", "stormy", "night."};
-
-Using the + operator along with a for loop, we can join an array of strings together as follows:
- + Using the “+” operator along with afor loop, you can join a string together as follows:
// Manual Concatenation
String onelongstring = "";
for (int i = 0; i < lines.length; i++) {
- onelongstring = onelongstring + lines[i] + " ";
+ onelongstring = onelongstring + lines[i] + " ";
}
-
-The join() function, however, allows us to bypass this process achieving the same result in only one line of code.
- + The join() function, however, allows you to bypass this process, achieving the same result in only one line of code.// Using Processing's join() -String onelongstring = join(lines," "); +String onelongstring = join(lines, " ");+ -
Data can come from many different places: web sites, news feeds, databases, etc. To start, we'll demonstrate how to work with the simplest means of data retrieval data: reading from a text file.Text files can be used as a very simple database (we could store settings for a program, a list of high scores, numbers for a graph, etc.) or to simulate a more complex data source.
- -In order to create a text file, you can use any simple text editor. Windows Notepad or Mac OSX TextEdit will do, just make sure you format the file as "plain text." It is also advisable to name the text files with the ".txt" extension, just to avoid any confusion. And just as with image files, these text files should be placed in the sketch's "data" directory in order for them to be recognized by the Processing sketch.
- -Once the text file is in place, Processing's loadStrings() function is used to read the content of the file into an String array. The individual lines of text in the file each become an individual element in the array.
- -
+ + Data can come from many different places: websites, news feeds, spreadsheets, databases, and so on. Let's say you've decided to make a map of the world's flowers. After searching online you might find a PDF version of a flower encyclopedia, or a spreadsheet of flower genera, or a JSON feed of flower data, or a REST API that provides geolocated lat/lon coordinates, or some web page someone put together with beautiful flower photos, and so on and so forth. The question inevitably arises: “I found all this data; which should I use, and how do I get it into Processing?” +
+ +
+ If you are really lucky, you might find a Processing library that hands data to you directly with code. Maybe the answer is to just download this library and write some code like:
+
+import flowers.*;
+void setup() {
+ FlowerDatabase fdb = new FlowerDatabase();
+ Flower sunflower = fdb.findFlower("sunflower");
+ float h = sunflower.getAverageHeight();
+}
+
+ In this case, someone else has done all the work for you. They've gathered data about flowers and built a Processing library with a set of functions that hands you the data in an easy-to-understand format. This library, sadly, does not exist (not yet), but there are some that do. For example, YahooWeather is a library by Marcel Schwittlick that grabs weather data from Yahoo for you, allowing you to write code like weather.getWindSpeed() or weather.getSunrise() and more. There is still plenty of work to do in the case of using a library.
+
+
+ + Let's take another scenario. Say you’re looking to build a visualization of Major League Baseball statistics. You can't find a Processing library to give you the data but you do see everything you’re looking for at mlb.com. If the data is online and your web browser can show it, shouldn't you be able to get the data in Processing? Passing data from one application (like a web application) to another (say, your Processing sketch) is something that comes up again and again in software engineering. A means for doing this is an API or “application programming interface”: a means by which two computer programs can talk to each other. Now that you know this, you might decide to search online for “MLB API”. Unfortunately, mlb.com does not provide its data via an API. In this case you would have to load the raw source of the website itself and manually search for the data you’re looking for. While possible, this solution is much less desirable given the considerable time required to read through the HTML source as well as program algorithms for parsing it. +
+ ++ Each means of getting data comes with its own set of challenges. The ease of using a Processing library is dependent on the existence of clear documentation and examples. But in just about all cases, if you can find your data in a format designed for a computer (spreadsheets, XML, JSON, etc.), you'll be able to save some time in the day for a nice walk outside. +
+ ++ One other note worth a mention about working with data. When developing an application that involves a data source, such as a data visualization, it’s sometimes useful to develop with “dummy” or “fake” data. You don't want to be debugging your data retrieval process at the same time as solving problems related to algorithms for drawing. In keeping with my one-step-at-a-time mantra, once the meat of the program is completed with dummy data, you can then focus solely on how to retrieve the actual data from the real source. You can always use random or hard-coded numbers into your code when you’re experimenting with a visual idea and connect the real data later.
+ ++ Let's begin by working with the simplest means of data retrieval: reading from a text file. Text files can be used as a very simple database (you could store settings for a program, a list of high scores, numbers for a graph, etc.) or to simulate a more complex data source. +
+ ++ In order to create a text file, you can use any simple text editor. Windows Notepad or Mac OS X TextEdit will do; just make sure you format the file as “plain text.” It is also advisable to name the text files with the “.txt” extension, to avoid any confusion. And just as with image files, these text files should be placed in the sketch’s “data” directory in order for them to be recognized by the Processing sketch.
+ +
+ Once the text file is in place, Processing’s loadStrings() function is used to read the content of the file into a String array. The individual lines of text in the file each become an individual element in the array.
+
+
// This code will print all the lines from the source text file.
String[] lines = loadStrings("file.txt");
-println("there are " + lines.length + " lines");
-println(lines);
+println("There are " + lines.length + " lines.");
+printArray(lines);
-
-Text from a file can be used to generate a simple visualization. Take the following data file.
- -
-
-Here, we can load the numbers separated by commas and split them into an array of ints used to set color and height of rectangles.
- + To run the code, create a text file called “file.txt,” type a bunch of lines in that file, and place it in your sketch’s data directory.
+Graphing Comma-Separated Numbers from a Text File
+
+
int[] data;
void setup() {
- size(200,200);
- // Load text file as a string
- String[] stuff = loadStrings("data.txt");
+ size(200, 200);
+ // Load text file as a String
+ String[] stuff = loadStrings("data.csv");
// Convert string into an array of integers using ',' as a delimiter
- data = int(split(stuff[0],','));
+ data = int(split(stuff[0], ','));
}
void draw() {
background(255);
stroke(0);
- for (int i = 0; i < data.length; i++) {
- fill(data[i]);
- rect(i*20,0,20,data[i]);
+ for (int i = 0; i<data.length; i++) {
+ // Use array of ints to set the color and height of each rectangle.
+ rect(i*20, 0, 20, data[i]);
}
+ noLoop();
}
+ Looking at how to parse a csv file with split() was a nice learning exercise. In truth, dealing with csv files (which can easily be generated from spreadsheet software such as Google docs) is such a common activity that Processing has an entire built-in class called Table to handle the parsing for you.
+
+
+Text can also be written back to a data file with saveStrings(). saveStrings() writes an array of strings to a file, one line per string.
++ A table consists of data arranged as a set of rows and columns, also called “tabular data.” If you've ever used a spreadsheet, this is tabular data. Processing's loadTable() function takes comma-separated (csv) or tab-separated (tsv) values and automatically places the contents into a Table object storing the data in columns and rows. This is a great deal more convenient than struggling to manually parse large data files with split(). It works as follows. Let's say you have a data file that looks like: +
+
+
+
+ Instead of saying:
+
+String[] stuff = loadStrings("data.csv");
+
+ We can now say:
+Table table = loadTable("data.csv");
+
+ Now I've missed an important detail. Take a look again at the data.csv text file above. Notice how the first line of text is not the data itself, but rather a header row. This row includes labels that describe the data included in each subsequent row. The good news is that Processing can automatically interpret and store the headers for you, if you pass in the option "header" when loading the table. (In addition to "header", there are other options you can specify. For example, if your file is called data.txt but is comma separated data you can pass in the option "csv". If it also has a header row, then you can specifiy both options like so: "header,csv"). A full list of options can be found on the loadTable() documentation page.
+Table table = loadTable("data.csv", "header");
+
+ Now that the table is loaded, I can show how you grab individual pieces of data or iterate over the entire table. Let's look at the data visualized as a grid.
+
++int val1 = table.getInt(2, 1); // val now has the value 235 +float val2 = table.getFloat(3, 2); // val2 now has the value 44.758068 + +String s = table.getString(0, 3); // s now has the value “Happy” ++ While the numeric index is sometimes useful, it’s generally going to be more convenient to access each piece of data by the column name. For example, I could pull out a specific row from the Table.
+TableRow row = table.getRow(2); // Gets the third row (index 2) ++ Note in the above line of code that a Table object refers to the entire table of data while a TableRow object handles an individual row of data within the Table. + + +
+ Once I have the TableRow object, I can ask for data from some or all of the columns.
-String words = "apple bear cat dog";
-String[] list = split(words, ' ');
+int x = row.getInt("x"); // // x has the value 273
+
+int y = row.getInt("y"); // y has the value 235
+
+float d = row.getFloat("diameter"); // d has the value 61.14072
-// Writes the strings to a file, each on a separate line
-saveStrings("nouns.txt", list);
+String s = row.getString("name"); // s has the value “Joyous”
+ The method getRow() returns a single row from the table. If you want to grab all the rows and iterate over them you can do so in a loop with a counter accessing each row one at a time. The total number of available rows can be retrieved with getRowCount().
+for (int i = 0; i<table.getRowCount(); i++) {
-There are cases, however, where you don't want to write a text file all at once. Rather, you want to continuously append to a file over time. This can be achieved with the PrintWriter class. Take the following example which writes saves mouseX and mouseY to a text file for each cycle through draw(), quitting when you press a key.
+ // Access each row of the table one at a time, in a loop.
+ TableRow row = table.getRow(i);
+ float x = row.getFloat("x");
+ float y = row.getFloat("y");
+ float d = row.getFloat("diameter");
+ String n = row.getString("name");
+
+ // Do something with the data of each row
+
+}
+
+ If you want to search for a select number of rows within the table, you can do so with findRows() and matchRows().
+
+
+
+ In addition to being read, Table objects can be altered or created on the fly while a sketch is running. Cell values can be adjusted, rows can be removed, and new rows can be added. For example, to set new values in a cell there are functions setInt(), setFloat(), and setString().
+
+row.setInt("x", mouseX); // Update the value of column "x" to mouseX in a given TableRow.
+
+ To add a new row to a Table, simply call the method addRow() and set the values of each column.
+//Create a new row.
+TableRow row = table.addRow();
+//Set the values of all columns in that row.
+row.setFloat("x", mouseX);
+row.setFloat("y", mouseY);
+row.setFloat("diameter", random(40, 80));
+row.setString("name", "new label");
+
+ To delete a row, simply call the method removeRow() and pass in the numeric index of the row you would like removed. For example, the following code removes the first row whenever the size of the table is greater than ten rows.
-PrintWriter output;
+// If the table has more than 10 rows
+if (table.getRowCount()>10) {
+
+//Delete the first row (index 0).
+ table.removeRow(0);
+}
+
+ The following example puts all of the above code together. Notice how each row of the table contains the data for a Bubble object.
+
+
+
+Loading and Saving Tabular Data
+
+
+
+
+// The data from the Table object will fill the array of Bubble objects
+Table table;
+Bubble[] bubbles;
void setup() {
- // Create a new file in the sketch directory
- output = createWriter("positions.txt");
+ size(480, 360);
+ loadData();
}
void draw() {
- point(mouseX, mouseY);
- output.println(mouseX); // Write the coordinate to the file
+ background(255);
+ // Display all bubbles
+ for (int i = 0; i<bubbles.length; i++) {
+ bubbles[i].display();
+ }
}
-void keyPressed() {
- output.flush(); // Writes the remaining data to the file
- output.close(); // Finishes the file
- exit(); // Stops the program
+void loadData() {
+ // "header" indicates the file has header row. The size of the array
+ // is then determined by the number of rows in the table.
+ table = loadTable("data.csv", "header");
+ bubbles = new Bubble[table.getRowCount()];
+
+
+ for (int i = 0; i<table.getRowCount(); i++) {
+ // Iterate over all the rows in a table.
+ TableRow row = table.getRow(i);
+
+
+ // Access the fields via their column name (or index).
+ float x = row.getFloat("x");
+ float y = row.getFloat("y");
+ float d = row.getFloat("diameter");
+ String n = row.getString("name");
+ // Make a Bubble object out of the data from each row.
+ bubbles[i] = new Bubble(x, y, d, n);
+ }
}
-
-You may have noticed that the graphing example above loads a text file with numbers separated by commas. Processing includes a Table class which will load a comma-separated (CSV) or tab-separated (TSV) file and automatically parse the data into columns and rows for you. This is a great deal more convenient than struggling to manually parse large data files with split(). It works as follows. Let's say you have a data file that looks like:
+void mousePressed() { + // When the mouse is pressed, create a new row and set the values for each column of that row. + TableRow row = table.addRow(); + row.setFloat("x", mouseX); + row.setFloat("y", mouseY); + row.setFloat("diameter", random(40, 80)); + row.setString("name", "Blah"); -
+ // If the table has more than 10 rows, delete the oldest row.
+ if (table.getRowCount()>10) {
+ table.removeRow(0);
+ }
-Instead of saying:
+ // This writes the table back to the original CSV file + // and reloads the file so that what's drawn matches. + saveTable(table, "data/data.csv"); + loadData(); +} -
-String[] stuff = loadStrings("data.csv");
+// This simple Bubble class draws a circle to the window
+// and displays a text label when the mouse hovers.
+class Bubble {
+ float x, y;
+ float diameter;
+ String name;
+
+ boolean over = false;
+
+ // Create the Bubble
+ Bubble(float tempX, float tempY, float tempD, String s) {
+ x = tempX;
+ y = tempY;
+ diameter = tempD;
+ name = s;
+ }
+
+ // Checking if mouse is over the bubble
+ void rollover(float px, float py) {
+ float d = dist(px, py, x, y);
+ if (d<diameter/2) {
+ over = true;
+ } else {
+ over = false;
+ }
+ }
+
+ // Display the Bubble
+ void display() {
+ stroke(0);
+ strokeWeight(2);
+ noFill();
+ ellipse(x, y, diameter, diameter);
+ if (over) {
+ fill(0);
+ textAlign(CENTER);
+ text(name, x, y+diameter/2+20);
+ }
+ }
+}
-
-We can now say: + +
+ Here, the distance between a given point and a circle's center is compared to that circle's radius as depicted: +
+
+
+ + In the code below, the function returns a boolean value (true or false) depending on whether the point (mx,my) is inside the circle. Notice how radius is equal to half the diameter. +
-Table table = loadTable("data.csv");
+boolean rollover(int mx, int my) {
+ if (dist(mx, my, x, y)<diameter/2) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Now we've missed an important detail. Take a look at the data.csv text file above. Notice how the first line of text is not the data itself, but rather a "header row." This row includes labels that describe the data included in each subsequent row. The good news is that Processing can automatically interpret and store the headers for you, if you pass in the option "header" when loading the table. (In addition to "header" there are other options you can specify. For example if your file is called data.txt but is comma separated data you can pass in the option "csv". If it also has a header row, then you can specifiy both options like so: "header,csv"). A full list of options can be found on the loadTable() documentation page.
- +
+ What if your data is not in a standard format like a table, how do you deal with it then? One of the nice features about loadStrings() is that in addition to pulling text from a file, you can also grab a URL. For example:
-Table table = loadTable("data.csv","header");
+String[] lines = loadStrings("http://www.yahoo.com");
+ When you send a URL path into loadStrings(), you get back the raw HTML (Hypertext Markup Language) source of the requested web page. It’s the same stuff that appears upon selecting “View Source” from a browser’s menu options. You don’t need to be an HTML expert to follow this section, but if you are not familiar at all with HTML, you might want to read http://en.wikipedia.org/wiki/HTML.
+
+
+
+ Unlike with the comma-delimited data from a text file that was specially formatted for use in a Processing sketch, it’s not practical to have the resulting raw HTML stored in an array of strings (each element representing one line from the source). Converting the array into one long string can make things a bit simpler. As you saw earlier in the chapter, this can be achieved using join().
+
+String onelongstring = join(lines, " "); ++ When pulling raw HTML from a web page, it’s likely you do not want all of the source, but just a small piece of it. Perhaps you’re looking for weather information, a stock quote, or a news headline. You can take advantage of the text manipulation functions you learned — indexOf(), substring(), and length() — to find pieces of data within a large block of text. Take, for example, the following String object:
+String stuff = "Number of apples:62. Boy, do I like apples or what!"; ++Let’s say I want to pull out the number of apples from the above text. My algorithm would be as follows: + +
Find the end of the substring “apples:” Call it start.
+Find the first period after “apples:” Call it end.
+Make a substring of the characters between start and end.
+Convert the string to a number (if I want to use it as such).
+
+ In code, this looks like:
+
+int start = stuff.indexOf("apples:" ) + 7; // STEP 1
+// The index where a string ends can be found by
+// searching for that string and adding its length (here, 8).
+int end = stuff.indexOf(".", start); // STEP 2
+String apples = stuff.substring(start, end); // STEP 3
+int apple_no = int(apples); // STEP 4
+
+ The above code will do the trick, but I should be a bit more careful to make sure I don’t run into any errors if I do not find the string I am searching for. I can add some error checking and generalize the code into a function:
+// A function that returns a substring between two substrings.
+// If the beginning of end "tag" is not found, the function returns an empty string.
+String giveMeTextBetween(String s, String startTag, String endTag) {
+ // Find the index of the beginning tag
+ int startIndex = s.indexOf(startTag);
+ // If I don't find anything
+ if (startIndex == -1) {
+ return "";
+ }
+ // Move to the end of the beginning tag
+ startIndex += startTag.length();
-Now that the table is loaded, we can look at how we grab individual pieces of data or iterate over the entire table. Let's look at the data visualized as a grid.
-
-
-
-In the above grid we can see that the data is organized in terms of rows and columns. One way to access the data would be to therefore request a value by its numeric row and column location (with zero being the first row or first column). This is similar to accessing a pixel color at a given (x, y) location though in this case the y position (i.e. row) comes first. The following code requests a piece of data at a given (row, column) location.
-
+ // Find the index of the end tag
+ int endIndex = s.indexOf(endTag, startIndex);
+
+ // If I don't find the end tag,
+ if (endIndex == -1) {
+ return "";
+ }
+ // Return the text in between
+ return s.substring(startIndex, endIndex);
+}
+
+ With this technique, you are ready to connect to a website from within Processing and grab data to use in your sketches. For example, you could read the HTML source from nytimes.com and look for today’s headlines, search finance.yahoo.com for stock quotes, count how many times the word “flower” appears on your favorite blog, and so on. However, HTML is an ugly, scary place with inconsistently formatted pages that are difficult to reverse engineer and parse effectively. Not to mention the fact that companies change the source code of web pages rather often, so any example that I might make while I am writing this paragraph might break by the time you read this paragraph.
+
+
+ + For grabbing data from the web, an XML (Extensible Markup Language) or JSON (JavaScript Object Notation) feed will prove to be more reliable and easier to parse. Unlike HTML (which is designed to make content viewable by a human’s eyes) XML and JSON are designed to make content viewable by a computer and facilitate the sharing of data across different systems. Most data (news, weather, and more) is available this way, and I will look at examples in #beginner_xml and #JSON. Though much less desirable, manual HTML parsing is still useful for a couple reasons. First, it never hurts to practice text manipulation techniques that reinforce key programming concepts. But more importantly, sometimes there is data you really want that is not available in an API format, and the only way to get it is with such a technique. (I should also mention that regular expressions, an incredibly powerful techinque in text pattern matching, could also be employed here. As much as I love regex, it’s unfortunately beyond the scope of this tutorial.) +
+ ++ An example of data only available as HTML is the Internet Movie Database. IMDb contains information about movies sorted by year, genre, ratings, etc. For each movie, you can find the cast and crew list, a plot summary, running time, a movie poster image, the list goes on. However, IMDb has no API and does not provide its data as XML or JSON. Pulling the data into Processing therefore requires a bit of detective work. Let's look at the page for the Shaun the Sheep Movie +
+ +
+
+ + Looking in the HTML source from the above URL, I find a giant mess of markup. +
+ +
+
+
+ It’s up to me to pore through the raw source and find the data I am looking for. Let's say I want to know the running time of the movie and grab the movie poster image. After some digging, I find that the movie is 139 minutes long as listed in the following HTML.
-int val1 = table.getInt(2, 1); // val now has the value 235 -float val2 = table.getFloat(3, 2); // val2 now has the value 44.758068 -String s = table.getString(0, 3); // s now has the value "Happy" +<div class="txt-block"> + <h4 class="inline">Runtime:</h4> + <time itemprop="duration" datetime="PT139M">139 min</time> +</div>+ For any given movie, the running time itself will be variable, but the HTML structure of the page will stay the same. I can therefore deduce that running time will always appear in between:
+<time itemprop="duration" datetime="PT139M"> ++ and:
+</time> ++ Knowing where the data starts and ends, I can use giveMeTextBetween() to pull out the running time. A quote in Java marks the beginning or end of a string. So how do you include an actual quote in a String object? The answer is via an “escape” sequence. A quote can be included using a backward slash, followed by a quote. For example: String q = "This String has a quote \"in it";
+String url = "http://www.imdb.com/title/tt0058331"; +String[] lines = loadStrings(url); +// Get rid of the array in order to search the whole page +String html = join(lines, " "); -+ The following code retrieves both the running time and movie poster iamge from IMDb and displays it onscreen. + + + Parsing IMDb Manually +While the numeric index is sometimes useful, it's generally going to be more convenient to access each piece of data by the column name. For example, we could pull out a specific row from the Table.
+// Searching for running time +String start = ""; +String runningtime = giveMeTextBetween(html, start, end); +println(runningtime);
++String runningtime; +PImage poster; -Note in the above line of code that a Table object refers to the entire table of data while a TableRow object handles an individual row of data within the Table. +void setup() { + size(300, 350); + loadData(); +} -Once we have the TableRow object, we can ask for data from some or all of the columns. +void draw() { + // Display all the stuff I want to display + background(255); + image(poster, 10, 10, 164, 250); + fill(0); + text("Shaun the Sheep", 10, 300); + text(runningtime, 10, 320); +} --int x = row.getInt("x"); // x has the value 273 -int y = row.getInt("y"); // y has the value 235 -float d = row.getFloat("diameter"); // d has the value 61.14072 -String s = row.getString("name"); // s has the value "Joyous" -+void loadData() { + String url = "http://www.imdb.com/title/tt2872750/"; + + // Get the raw HTML source into an array of strings (each line is one element in the array). + // The next step is to turn array into one long string with join(). + String[] lines = loadStrings(url); + String html = join(lines, ""); + + String start = ""; + runningtime = giveMeTextBetween(html, start, end);Searching for running time. + + start = ""; + // Search for the URL of the poster image. + String imgUrl = giveMeTextBetween(html, start, end); + // Now, load that image! + poster = loadImage(imgUrl); +} -The method getRow() returns a single row from the table. If you want to grab all the rows and iterate over them you can do so with the method rows(). +String giveMeTextBetween(String s, String before, String after) { --for (TableRow row : table.rows()) { - float x = row.getFloat("x"); - float y = row.getFloat("y"); - float d = row.getFloat("diameter"); - String n = row.getString("name"); - // Do something with the data of each row + // This function returns a substring between two substrings (before and after). + // If it can’t find anything it returns an empty string. + String found = ""; + + // Find the index of before + int start = s.indexOf(before); + if (start == -1) { + return ""; + } + + // Move to the end of the beginning tag + // and find the index of the "after" String + start += before.length(); + int end = s.indexOf(after, start); + if (end == -1) { + return ""; + } + + // Return the text in between + return s.substring(start, end); }-If you want to search for a select number of rows within the table, you can do so with findRows() and matchRows(). - -In addition to being read, Table objects can be altered or created on the fly while a sketch is running. Cell values can be adjusted, rows can be removed, and new rows can be added. For example, to set new values in a cell there are functions setInt(), setFloat(), and setString(). - +
Text Analysis
+ ++ Loading text from a URL need not only be an exercise in parsing out small bits of information. It’s possible with Processing to analyze large amounts of text found on the web from news feeds, articles, and speeches, to entire books. A nice source is Project Gutenberg which makes available thousands of public domain texts. Algorithms for analyzing text merits an entire book itself, but let’s look at some basic techniques. +
+ ++ A text concordance is an alphabetical list of words that appear in a book or body of text along with contextual information. A sophisticated concordance might keep a list of where each word appears (like an index) as well as which words appear next to which other words. In this case, I'm going to create a simple concordance, one that simply stores a list of words and their corresponding counts, i.e., how many times they appeared in the text. Concordances can be used for text analysis applications such as spam filtering or sentiment analysis. To accomplish this task, I am going to use the Processing built-in class IntDict. +
+ ++ As you learned earlier, an array is an ordered list of variables. Each element of the array is numbered and be accessed by its numeric index. +
++
+ However, what if instead of numbering the elements of an array you could name them? This element is named “Sue,” this one “Bob,” this one “Jane,” and so on and so forth. In programming, this kind of data structure is often referred to as an associative array, map, or dictionary. It’s a collection of (key, value) pairs. Imagine you had a dictionary of people's ages. When you look up “Sue” (the key), the definition, or value, is her age, 24. +
++
+ Associative arrays can be incredibly convenient for various applications. For example, you could keep a list of student IDs (student name, id) or a list of prices (product name, price) in a dictionary. Here a dictionary is the perfect data structure to hold the concordance. Each element of the dictionary is a word paired with its count. +
+ ++ While there are many classes in Java for dealing with advanced data structures like maps, Processing provides you with a set of three built-in dictionary classes that are easy to use: IntDict, FloatDict, and StringDict. In all of these classes, the key is always a string while the value is variable (an integer, floating point number, or String). For the concordance, I'll use an IntDict. +
+ ++ Creating an IntDict is as easy as calling an empty constructor. Let's say you want a dictionary to keep track of an inventory of supplies.
-// Update the value of column "x" to mouseX in a given TableRow. -row.setInt("x",mouseX); +IntDict inventory = new IntDict();- -To add a new row to a Table, simply call the method addRow() and set the values of each column.
- + Values can be paired with their keys using the set() method.
-// Create a new row -TableRow row = table.addRow(); -// Set the values of that row -row.setFloat("x", mouseX); -row.setFloat("y", mouseY); -row.setFloat("diameter", random(40, 80)); -row.setString("name", "new label"); +// set() assigns an integer to a String. +inventory.set("pencils", 10); +inventory.set("paper clips", 128); +inventory.set("pens, 16"); ++ There are a variety of other methods that can be called to change the value associated with a particular key. For example, if you wanted to add five pencils, you can use add().
++inventory.add("pencils", 5); // The value of “pencils” is now 15.-To delete a row to a Table, simply call the method removeRow() and pass in the numeric index of the row you would like removed. The following code for example, removes the first row whenever the size of the table is greater than ten rows.
- + A particularly convenient method for the concordance example is increment() which adds one to a key's value.
-// If the table has more than 10 rows -if (table.getRowCount() > 10) { - // Delete the first row - table.removeRow(0); -} +inventory.increment("pens"); // The value of “pencils” is now 16.+ To retrieve a value associated with a particular key, the get() method is used.
++int num = inventory.get("pencils"); // The value of num is 16. ++ Finally, dictionaries can be sorted by their keys (alphabetical) or values (smallest to largest or the reverse) with the methods sortKeys(), sortKeysReverse(), sortValues(), and sortValuesReverse(). + + ++ The concordance now becomes a rather simple program to write. All I need to do is load in a text file, chop it into words with splitTokens() and call increment() on an IntDict for every single word found in the text. The following example does precisely this with the entire text of Shakespeare’s play, A Midsummer Night's Dream, displaying a simple graph of the most used words. +
+ +Text Concordance Using IntDict +
++
+String[] allwords; -+For an example that creates objects from and saves objects to a Table, take a look at LoadSaveTable under Topics --> Advanced Data.
+// Any punctuation is used as a delimiter. +String delimiters = " ,.?!;:[]"; -XML Data
+IntDict concordance; -For grabbing data from the web, an XML (Extensible Markup Language) feed is an excellent option (if available). Unlike HTML (which is designed to make content vieweable by a human's eyes) XML is designed to make content viewable by a computer and facilitate the sharing of data across different systems.
+void setup() { + size(360, 640); + + // Load A Midsummer Night's Dream into an array of strings + String url = "http://www.gutenberg.org/cache/epub/1514/pg1514.txt"; + String[] rawtext = loadStrings(url); + + // Join the big array together as one long string + String everything = join(rawtext, "" ); -XML organizes information in a tree structure. Let's imagine a list of students. Each student has an id number, name, address, e-mail, and telephone number. Each student's address has a city, state, and zip code. An XML tree for this dataset might look like the following:
+ // All the lines in A Midsummer Night's Dream are first joined as one big string + // and then split up into an array of individual words. + // Note the use of splitTokens() since I am using spaces and punctuation marks as delimiters. + allwords = splitTokens(everything, delimiters); -+ // Make a new empty dictionary + concordance = new IntDict(); + + for (int i = 0; i<allwords.length; i++) { + // It's useful to convert each word to lower case so that, + // for example, “The” and “the” are both counted as the same word. + String s = allwords[i].toLowerCase(); + // For every single word, increase its count in the dictionary. + concordance.increment(s); + } + + // Sort the dictionary so that words that appear most often are first. + concordance.sortValuesReverse(); +} + +void draw() { + background(255); + + // Display the text and total times the word appears + int h = 20; + // In order to iterate over every word in the dictionary, + // first ask for an array of all of the keys. + String[] keys = concordance.keyArray(); + + for (int i = 0; i<height/h; i++) { + // Look at each key one at a time and retrieve its count. + String word = keys[i]; + int count = concordance.get(word); + + fill(51); + // Displaying a rectangle along with the count as a simple graph. + rect(0, i*20, count/4, h-4); + fill(0); + text(word + ": " + count, 10+count/4, i*h+h/2); + stroke(0); + } +} +
+ Processing also includes three classes for lists of numbers and strings: IntList, FloatList, and StringList. In other words, if you just want a list of words (without their counts) you could use a StringList rather than an IntDict. +
+ ++ If your data is available via a standardized format such as XML or JSON, the process of manually searching through text for individual pieces of data is no longer required. XML is designed to facilitate the sharing of data across different systems, and you can retrieve that data using the built-in Processing XML class. +
+ ++ XML organizes information in a tree structure. Let’s imagine a list of students. Each student has an ID number, name, address, email, and telephone number. Each student’s address has a city, state, and zip code. An XML tree for this dataset might look like the following: +
++
+ The XMl source itself (with two students listed) is:
-<?xml version="1.0" encoding="UTF-8"?> +<?xml version = "1.0" encoding = "UTF-8 "?> <students> <student> <id>001</id> @@ -313,94 +803,177 @@- -XML Data
<address> <street>45.3 Nebula 5</street> <city>Boolean City</city> - <state&tt;Booles</state> + <state>Booles</state> <zip>12358</zip> </address> </student> </students>Note the similarities to object-oriented programming. We could think of the XML tree in the following terms. The XML document represents an array of student objects. Each student object has multiple pieces of information, an id, a name, a phone number, an e-mail address, and a mailing address. The mailing address is also an object that also has multiple pieces of data, such as street, city, state, and zip.
- -Let's look at Yahoo's XML feed for weather data. Here is the raw XML source (Note I have edited it for simplification purposes).
- + Note the similarities to object-oriented programming. You can think of the XML tree in the following terms. The XML document represents an array of student objects. Each student object has multiple pieces of information, an ID, a name, a phone number, an email address, and a mailing address. The mailing address is also an object that has multiple pieces of data, such as street, city, state, and zip. + + ++ Let's look at some data made available from a web service such as Yahoo Weather. Here is the raw XML source. (Note I have edited it slightly for simplification purposes.)
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"> <channel> <item> - <title>Conditions for New York, NY at 3:51 pm EST</title> + <title>Conditions for New York, NY at 12:49 pm EDT</title> <geo:lat>40.67</geo:lat> <geo:long>-73.94</geo:long> - <link>http://xml.weather.yahoo.com/forecast/USNY0996_f.html</link> - <pubDate>Mon, 20 Feb 2006 3:51 pm EST</pubDate> - <yweather:condition text="Fair" code="34" temp="35" date="Mon, 20 Feb 2006 3:51 pm EST"/> - <yweather:forecast day="Mon" date="20 Feb 2006" low="25" high="37" text="Clear" code="31"/> + <link>http://us.rd.yahoo.com/dailynews/rss/weather/New_York__NY//link> + <pubDate>Thu, 24 Jul 2014 12:49 pm EDT</pubDate> + <yweather:condition text="Partly Cloudy" code="30" temp="76"/> + <yweather:forecast day="Thu" low="65" high="82" text="Partly Cloudy"/> </item> </channel> </rss>- -And here is the data mapped in the tree structure.
- -- -
You may be wondering what the top level "RSS" is all about. Yahoo's XML weather data is provided in RSS format. RSS stands for "Really Simple Syndication" and is a standardized XML format for syndicating web content (such as news articles, etc.)
- -Now that we have a handle on the tree structure, we should look at the specifics inside that structure. With the exception of the first line (which simply indicates that this page is XML formatted), this XML document contains a nested list of elements, each with a start tag, i.e. <channel> and an end tag, i.e. </channel>. Some of these elements have content between the tags:
- + The data is mapped in the tree stucture shown below: + ++
+ You may be wondering what the top level “RSS” is all about. Yahoo’s XML weather data is provided in RSS format. RSS stands for “Really Simple Syndication” and is a standardized XML format for syndicating web content (such as news articles, etc.). You can read more about RSS on Wikipedia. +
+ +Now that you have a handle on the tree structure, let's look at the specifics inside that structure. With the exception of the first line (which simply indicates that this page is XML formatted), this XML document contains a nested list of elements, each with a start tag, that is, <channel>, and an end tag, that is, </channel>. Some of these elements have content between the tags:
-<title>Conditions for New York, NY at 3:51 pm EST</title> +<title>Conditions for New York, NY at 12:49 pm EDT</title>- -and some have attributes (formatted by attribute name equals attribute value in quotes):
- +and some have attributes (formatted by Attribute Name equals Attribute Value in quotes):
-<yweather:condition text="Fair" code="34" temp="35" date="Mon, 20 Feb 2006 3:51 pm EST"/> +<yweather:forecast day="Thu" low="65" high="82" text="Partly Cloudy"/>+ -Knowing this format, we could certainly be clever with our use of split(), indexOf(), and substring() to find the pieces we want in the raw XML. The point here, however, is that because XML is a standard format, we don't have to do this. Rather, we can use an XML parser. In Processing, the XML parser is called just that: XML.
+Using the Processing XML Class
++ Since the syntax of XML is standardized, I could certainly use split(), indexof(), and substring() to find the pieces I want in the XML source. The point here, however, is that because XML is a standard format, I don't have to do this. Rather, I can use an XML parser. In Processing, XML can be parsed using the built-in Processing class XML.
XML xml = loadXML("http://xml.weather.yahoo.com/forecastrss?p=10003");+ Here, instead of loadStrings() or loadTable(), I'm now calling loadXML() and passing in the address (URL or local file) of the XML document. An XML object represents one element of an XML tree. When a document is first loaded, that XML object is always the root element. Referring back to XML tree diagram from Yahoo Weather, I find the current temperature via the following path: + + ++
+ +- +
+The root of the tree is RSS.
+- +
+RSS has a child named channel.
+- +
+Channel has a child named item.
+- +
+Item has a child named yweather:condition.
+- +
+The temperature is stored in yweather:condition as the attribute temp.
++ The children of an element are accessed via the getChild() function.
++// Accessing the “channel” child element of the root element --> +XML channel = xml.getChild("channel"); ++ The content of an element itself is retrieved with one of the following methods: getContent(), getIntContent(), or getFloatcContent(). getContent() is for generic use and will always give you the content as a String. If you intend to use the content as a number, Processing will convert it for you with either getIntContent() or getFloatcContent(). Attributes can also be read as either numbers — getInt(), getFloat() — or text — getString(). + -Here, instead of loadStrings() or loadTable(), we're now calling loadXML() and passing in the address (URL or local file) of our XML document. An XML object represents one element of an XML tree. When a document is first loaded, that XML object is always the root element. Referring back to XML tree diagram, we see that we can find the current temperature via the following path:
- --
+- The root of the tree is RSS.
-- RSS has a child named channel.
-- Channel has a child named item.
-- Item has a child named yweather:condition.
-- The temperature is stored in yweather:condition as the attribute temp.
-+ Following steps one through five outlined above through the XML tree, I have:
++XML root = loadXML("http://xml.weather.yahoo.com/forecastrss?p=10003"); // Step 1 -We could translate the above into code as follows:
+XML channel = root.getChild("channel"); // Step 2 --XML root = loadXML("http://xml.weather.yahoo.com/forecastrss?p=10003"); // Step 1 -XML channel = root.getChild("channel"); // Step 2 -XML item = channel.getChild("item"); // Step 3 -XML yweather = item.getChild("yweather:condition"); // Step 4 -int temperature = yweather.getInt("temp"); // Step 5 -+XML item = channel.getChild("item"); // Step 3 -This is a bit long-winded, however, and so can be compressed down into one (or three as below) lines of code.
+XML yweather = item.getChild("yweather:condition"); // Step 4 --XML root = loadXML(http://xml.weather.yahoo.com/forecastrss?p=10003); // Step 1 -XML forecast = root.getChild("channel").getChild("item").getChild("yweather:condition"); // Steps 2-4 -int temperature = forecast.getInt("temp"); // Step 5 +int temperature = yweather.getInt("temp"); // Step 5+ However, this is a bit long-winded and so can be compressed down into one (or three, as below) lines of code.
++XML root = loadXML(http://xml.weather.yahoo.com/forecastrss?p=10003); -Finally, the second line of code above can be further condensed to: - +XML forecast = + root.getChild("channel").getChild("item").getChild("yweather:condition"); // Steps 2-4 +int temperature = forecast.getInt("temp"); ++ Finally, the second line of code above can be further condensed to:
XML forecast = xml.getChild("channel/item/yweather:condition"); // Steps 2-4+ Following is the above code put together in an example that retrieves weather data for multiple zip codes by parsing Yahoo's XML feed. + ++Parsing Yahoo Weather XML +
+
+int temperature = 0;Temperature is stored as a number and the description of the weather as a string. +String weather = ""; + + +// The zip code +String zip = "10003"; + +void setup() { + size(200, 200); + + // The URL for the XML document + String url = "http://xml.weather.yahoo.com/forecastrss?p=" + zip; -+ Other useful XML functions are: + + +It should also be noted that we're accessing the child nodes by their name (i.e. "channel", "item", etc.), but they can also be accessed numerically via an index (starting at zero, same as an array). This is convenient when looping over a list of children. In LoadSaveTable, we used a series of comma separated values in a text file to store information related to Bubble objects. An XML document can also be used in the same manner. Consider the following XML document:
+ // Load the XML document + XML xml = loadXML(url); + // Here, I grab the XML element that I want. + XML forecast = xml.getChild("channel/item/yweather:forecast"); + + // And then I pull the attributes from that XML element. + temperature = forecast.getInt("high"); + weather = forecast.getString("text"); +} + +void draw() { + background(255); + fill(0); + + // Display all the stuff I want to display + text("Zip code: " + zip, 10, 50); + text("Today’s high: " + temperature, 10, 70); + text("Forecast: " + weather, 10, 90); +} +
hasChildren() — checks whether or not an element has any children
+getChildren() — returns an array containing all child elements
+getAttributeCount() — counts the specified element's number of attributes
+hasAttribute() — checks whether or not an element has the specified attribute
++ In this example I'm accessing the child nodes by their name (i.e., "channel," "item,", etc.), however they can also be accessed numerically via an index (starting at zero, same as an array). This is convenient when looping over a list of children, much like I did with tabular data when I iterated over rows in a table. +
+ +
+ Earlier, we used a Table to store information related to Bubble objects. XML document can also be used in the same manner. Here is a possible solution for an XML tree of Bubble objects:
<?xml version="1.0" encoding="UTF-8"?> <bubbles> @@ -426,52 +999,321 @@+ I can use getChildren() to retrieve the array of <bubble> elements and make a Bubble object from each one. Here is the example which uses the identical Bubble class from earlier (not included below). The new code is in bold. + + +XML Data
</bubble> </bubbles>
+Using Processing's XML Class
+
+
+// An Array of Bubble objects
+Bubble[] bubbles;
+// An XML object
+XML xml;
+
+void setup() {
+ size(480, 360);
+ loadData();
+}
-In the above XML, the root element is "bubbles" which has four children. Each child "bubble" has 3 children, "position", "diameter", and "label." The "position" element has two attributes, "x" and "y." To access the list of all XML nodes "bubble" we can use the getChildren() method, passing in the name "bubble"
+void loadData() {
+ // Load XML file
+ xml = loadXML("data.xml");
+ // Get all the child nodes named "bubble"
+ XML[] children = xml.getChildren("bubble");
+ bubbles = new Bubble[children.length];
+ // The size of the Bubble array is determined by the total XML elements named “bubble.”
+
+ for (int i = 0; i < bubbles.length; i++) {
+
+ XML positionElement = children[i].getChild("position");
+ // The position element has two attributes: “x” and “y”.
+ // Attributes can be accessed as an integer or float via getInt() and getFloat().
+ float x = positionElement.getInt("x");
+ float y = positionElement.getInt("y");
+
+ // The diameter is the content of the child named "diameter"
+ XML diameterElement = children[i].getChild("diameter");
+ float diameter = diameterElement.getFloatContent();
+ // Notice, however, with the content of an XML node,
+ // I retrieve via getIntContent() and getFloatContent().
+
+ // The label is the content of the child named "label"
+ XML labelElement = children[i].getChild("label");
+ String label = labelElement.getContent();
+
+ // Make a Bubble object out of the data read
+ bubbles[i] = new Bubble(x, y, diameter, label);
+ }
+}
+
+void draw() {
+ background(255);
+ // Display all bubbles
+ for (int i = 0; i < bubbles.length; i++) {
+ bubbles[i].display();
+ bubbles[i].rollover(mouseX, mouseY);
+ }
+}
+
+ In addition to loadXML(), Processing also includes a saveXML() function for writing XML files to your sketch folder. You can modify the XML tree itself by adding or removing elements with addChild() or removeChild(), as well as modify the content of elements or attributes with setContent(), setIntContent(), setFloatContent(), setString(), setInt(), and setFloat().
+
+
++ Another increasingly popular data exchange format is JSON (pronounced like the name Jason), which stands for JavaScript Object Notation. Its design was based on the syntax for objects in the JavaScript programming language (and is most commonly used to pass data between web applications) but has become rather ubiquitous and language-agnostic. While you don't need to know anything about JavaScript to work in Processing, it won't hurt to get a sense of some basic JavaScript syntax while learning it. +
+ ++ JSON is an alternative to XML and the data can be looked at in a similarly tree-like manner. All JSON data comes in the following two ways: an object or an array. Luckily, you already know about these two concepts and only need to learn a new syntax for encoding them. +
+ +
+ Let's take a look at a JSON object first. A JSON object is like a Processing object only with no functions. It’s simply a collection of variables with a name and a value (or "name/value pair"). For example, following is JSON data describing a person:
+
+{
+ "name":"Olympia",
+ // Each name/value pair is separated by a comma.
+ "age":3,
+ "height":96.5,
+ "state":"giggling"
+}
+Notice how this maps closely to classes in Processing.
+
+class Person {
+ String name;
+ int age;
+ float height;
+ String state;
+}
+
+ There are no classes in JSON, only the object literals themselves. Also an object can contain, as part of itself, another object.
+{
+ "name":"Olympia",
+ "age":3,
+ "height":96.5,
+ "state":"giggling",
+ // The value of “brother” is an object containing two name/value pairs.
+ "brother":{
+ "name":"Elias",
+ "age":6
+ }
+}
+ In XML, the preceding JSON data would look like the following (for simplicity I'm avoiding the use of XML attributes).+<xml version="1.0" encoding="UTF-8"?> +<person> + <name>Olympia</name> + <age>3</age> + <height>96.5</height> + <state>giggling</state> + <brother> + <name>Elias</name> + <age>6</age> + </brother> +</person> ++ Multiple JSON objects can appear in the data as an array. Just like the arrays you use in Processing, a JSON array is simply a list of values (primitives or objects). The syntax, however, is different with square brackets indicating the use of an array rather than curly ones. Here is a simple JSON array of integers:
+[1, 7, 8, 9, 10, 13, 15] ++ You might find an array as part of an object.
+{
+ "name":"Olympia",
+ // The value of “favorite colors” is an array of strings.
+ "favorite colors":[
+ "purple",
+ "blue",
+ "pink"
+ ]
+}
+
+ Or an array of objects themselves. For example, here is what the bubbles would look like in JSON. Notice how this JSON data is organized as a single JSON object "bubbles," which contains a JSON array of JSON objects, the bubbles. Flip back to compare to the CSV and XML versions of the same data.
+{
+ "bubbles":[
+ {
+ "position":{
+ "x":160,
+ "y":103
+ },
+ "diameter":43.19838,
+ "label":"Happy"
+ },
+ {
+ "position":{
+ "x":372,
+ "y":137
+ },
+ "diameter":52.42526,
+ "label":"Sad"
+ },
+ {
+ "position":{
+ "x":273,
+ "y":235
+ },
+ "diameter":61.14072,
+ "label":"Joyous"
+ }
+ ]
+}
+
+
++ Now that I've covered the syntax of JSON, I can look at using the data in Processing. One thing that can be a bit tricky about working with JSON in Processing is that I have to treat objects and arrays differently. With XML, I simply had a single XML class with all the parsing functionality I needed. With JSON, I have two classes: JSONObject and JSONArray, and I'll have to be conscientious about picking which class I am using during the parsing process. +
+ ++ The first step is simply loading the data with either loadJSONObject() or loadJSONArray(). But which one? I have to look and see what is at the root of the JSON file, an object or array. This can be a little tricky. Let's look at these two JSON examples: +
+ +
+ Sample 1:
+
+[
+ {
+ "name":"Elias"
+ },
+ {
+ "name":"Olympia"
+ }
+]
+
+ Sample 2:
-// Load an XML document
-XML xml = loadXML("bubbles.xml");
+{
+ "names":[
+ {
+ "name":"Elias"
+ },
+ {
+ "name":"Olympia"
+ }
+ ]
+}
+
+ Look how similar the above two samples look. They both contain exactly the same data, two names "Elias" and "Olympia." There is one, very key difference, however, to how the data is formatted: the very first character. Is it a "[" or a "{"? The answer will determine whether you’re loading an array ("[") or an object("{"). JSON objects start with a curly bracket, while JSON arrays start with a square bracket.
+JSONObject json = loadJSONObject("file.json");
-// Get all the child elements
-XML[] children = xml.getChildren("bubble");
+JSONArray json = JSONArray("file.json");
+ Typically, even if the data is ultimately organized as an array of objects (such as the array of "bubble" objects), the root element of the JSON data will be an object that contains that array. Let's look at the bubble data one more time.
+{
+ "bubbles":[
+ {
+ "position":{
+ "x":160,
+ "y":103
+ },
+ "diameter":43.19838,
+ "label":"Happy"
+ },
+ {
+ "position":{
+ "x":372,
+ "y":137
+ },
+ "diameter":52.42526,
+ "label":"Sad"
+ }
+ ]
+}
+
+ With the above, I first load an object and then pull the array out of that object.
+JSONObject json = loadJSONObject("data.json");
+JSONArray bubbleData = json.getJSONArray("bubbles");
+
+ Just as with XML, the data from an element is accessed via its name, in this case "bubbles." With a JSONArray, however, each element of the array is retrieved via its numeric index. The following code iterates over a JSONArray.
+for (int i = 0; i < bubbleData.size(); i++) {
+ JSONObject bubble = bubbleData.getJSONObject(i);
+ }
+
+ And when you're looking for a specific piece of data from a JSONObject, such as an integer or string, the functions are identical to those of XML attributes. The following code gets the position object from the bubble object, then gets x and y as integers from the position object. The diameter and label are then available directly from the Bubble object.
+ JSONObject position = bubble.getJSONObject("position");
-Once we have the array of XML objects, we can iterate over them, accessing the individual pieces of data for each "bubble". Notice how the syntax for getting XML attributes (in this case, "x" and "y" of the position element is slightly different than pulling content directly from an element (in this case, "diameter" and "label").
-
-for (int i = 0; i < bubbles.length; i++) {
-
- // The position element has two attributes: x and y
- XML positionElement = children[i].getChild("position");
- // Note how with attributes we can get an integer or float via getInt() and getFloat()
- float x = positionElement.getInt("x");
- float y = positionElement.getInt("y");
-
- // The diameter is the content of the child named "diamater"
- XML diameterElement = children[i].getChild("diameter");
- // Note how with the content of an XML node, we retrieve via getIntContent() and getFloatContent()
- float diameter = diameterElement.getFloatContent();
+ int x = position.getInt("x");
+ int y = position.getInt("y");
- // The label is the content of the child named "label"
- XML labelElement = children[i].getChild("label");
- String label = labelElement.getContent();
-}
+ float diameter = bubble.getFloat("diameter");
+ String label = bubble.getString("label");
+ Putting this all together, I can now make a JSON version of the bubbles example (leaving out the draw() function and Bubble class which haven't changed.)
+
+
+
+Using Processing's JSON Classes
+
+
+// An Array of Bubble objects
+Bubble[] bubbles;
-XML elements can be added and removed from the XML tree with the addChild() and removeChild() methods.
+void setup() {
+ size(480, 360);
+ loadData();
+}
-For the full example that creates objects from and saves objects to an XML document, take a look at LoadSaveXML under Topics --> Advanced Data.
+void loadData() {
+ // Load the JSON file and grab the array.
+ JSONObject json = loadJSONObject("data.json");
+ JSONArray bubbleData = json.getJSONArray("bubbles");
-Threads
+ // The size of the array of Bubble objects is determined by the length of the JSON array.
+ bubbles = new Bubble[bubbleData.size()];
+
+
+ for (int i = 0; i<bubbleData.size(); i++) {
+
+ // Iterate through the array, grabbing each JSON object one at a time.
+ JSONObject bubble = bubbleData.getJSONObject(i);
-You are likely familiar with the idea of writing a program that follows a specific sequence of steps -- setup() first then draw() over and over and over again! A Thread is also a series of steps with a beginning, a middle, and an end. A Processing sketch is a single thread, often referred to as the "Animation" thread. Other threads sequences, however, can run independently of the main Processing sketch. In fact, you can launch any number of threads at one time and they will all run concurrently.
+ // Get a position object
+ JSONObject position = bubble.getJSONObject("position");
+ // Get (x,y) from JSON object "position"
+ int x = position.getInt("x");
+ int y = position.getInt("y");
+
+ // Get diamter and label
+ float diameter = bubble.getFloat("diameter");
+ String label = bubble.getString("label");
-Processing does this all the time, whenever you write an event callback, such as serialEvent(), or captureEvent(), etc. these functions are triggered by a different thread running behind the scenes, and they alert Processing whenever they have something to report. This is useful whenever you need to perform a task that takes too long and would slow down the main animation's frame rate, such as grabbing data from the network (XML, database, etc.) If a separate thread gets stuck or has an error, the entire program won't grind to a halt, since the error only stops that individual thread. To create independent, asynchronous threads, you can use the thread() function built into Processing.
+ // Put the Bubble objects into an array.
+ bubbles[i] = new Bubble(x, y, diameter, label);
+ }
+}
+
+
+Threads
+
+ As you have seen, the various loading functions — loadStrings(), loadTable(), loadXML(), and loadJSONObject() — can be used for retrieving data from URLs. Nonetheless, unless your sketch only needs to load the data once during setup(), you may have a problem. For example, consider a sketch that grabs the price of AAPL stock from an XML feed every five minutes. Each time loadXML() is called, the sketch will pause while waiting to receive the data. Any animation will stutter. This is because these loading functions are “blocking.” In other words, the sketch will sit and wait at that line of code until loadXML() completes its task. With a local data file, this is extremely fast. Nonetheless, a request for a URL (known as an “HTTP request”) in Processing is synchronous, meaning your sketch waits for a response from the server before continuing. Who knows how will that take? No one; you are at the mercy of the server!
+
+
+
+ The answer to this problem lies in the concept of threads. By now you are quite familiar with the idea of writing a program that follows a specific sequence of steps — setup() first then draw() over and over and over again! A thread is also a series of steps with a beginning, a middle, and an end. A Processing sketch is a single thread, often referred to as the animation thread. Other threads’ sequences, however, can run independently of the main animation loop. In fact, you can launch any number of threads at one time, and they will all run concurrently.
+
+
+
+
+ Processing does this quite often, such as with library functions like captureEvent() and movieEvent(). These functions are triggered by a different thread running behind the scenes, and they alert Processing whenever they have something to report. This is useful when you need to perform a task that takes too long and would slow down the main animation's frame rate, such as grabbing data from the network. Here, you want to handle the request asynchronously in a different thread. If that thread gets stuck or has an error, the entire program won't grind to a halt, since the error only stops that individual thread and not the main animation loop.
+
+
+
+ Writing your own thread can be a complex endeavor that involves extending the Java Thread class. However, the thread() method is a quick and dirty way to implement a simple thread in Processing. By passing in a string that matches the name of a function declared elsewhere in the sketch, Processing will execute that function in a separate thread. Let's take a look at a skeleton of how this works.
void setup() {
- size(200,200);
thread("someFunction");
}
@@ -484,44 +1326,201 @@ Threads
// thread("someFunction") as it was in setup!
}
+ The thread() function receives a string as an argument. The string should match the name of the function you want to run as a thread. In the above example it’s "someFunction".
+
+
+
+ Let's look at a more practical example. For an example of data that changes often, I'll use time.jsontest.com which gives you the current time (in milliseconds). While I could retrieve this from the system clock, this works well for demonstrating continuously requesting data that changes over time. Not knowing about threads, my first instinct might be to say:
+
+void draw() {
+ // The code will stop here and wait to receive the data before moving on.
+ JSONObject json = loadJSONObject("http://time.jsontest.com/");
+ String time = json.getString("time");
+ text(time, 40, 100);
+}
+
+ This would give me the current time every cycle through draw(). If I examine the frame rate, however, I'll notice that the sketch is running incredibly slowly (and all it needs to do is draw a single string!). This is where calling the parsing code as a separate thread will help a lot.
+
+String time = "";
-The thread() function receives a String as an argument. The String should match the name of the function you want to run as a thread. This is especially useful in sketches that grab data for the web. Rather than have the animation freeze while the sketch is waiting to retrieve data, the sketch can continue to loop through draw() updating the data when the thread is completed. In these cases, a boolean variable can be useful to track the status of the thread.
+void draw() {
+ // Now the code will move on to the next line while requestData() executes in a separate thread.
+ thread("requestData");
+ text(time, 40, 100);
+}
-
-boolean loading = false;
+void requestData() {
+ JSONObject json = loadJSONObject("http://time.jsontest.com/");
+ time = json.getString("time");
+}
+ The logic is identical, only I am not requesting the data directly in draw(), but executing that request as a separate thread. Notice that I am not doing any drawing in requestData(). This is key as executing drawing functions in code that runs on a separate thread can cause conflicts with the main animation thread (i.e., draw()) resulting in strange behavior and errors.
+
-The function that loads the data can then set loading equal to true at the start and false at the end.
+
+ In the above example, I likely don't want to request the data sixty times per second (the default frame rate). Instead I might make use of the Timer class, and ask for the data once per second. Here is a full example that does exactly that with added animation to show that draw() never stutters.
+
+Threads
+
+
+
-void loadData() {
- loading = true;
+Timer timer = new Timer(1000);
+String time = "";
- ///////////////////////////////////
- // All of the data retrival code //
- ///////////////////////////////////
+void setup() {
+ size(200, 200);
+ // Start by requesting the data asynchronously in a thread.
+ thread("retrieveData");
+ timer.start();
+}
+
+void draw() {
+ background(255);
+ // Every one second, make a new request.
+ if (timer.isFinished()) {
+ retrieveData();
- loading = false;
+ // And restart the timer.
+ timer.start();
+ }
+
+ fill(0);
+ text(time, 40, 100);
+
+ translate(20, 100);
+ stroke(0);
+ //Draw a little animation to demonstrate that the draw() loop never pauses.
+ rotate(frameCount*0.04);
+ for (int i = 0; i<10; i++) {
+ rotate(radians(36));
+ line(5, 0, 10, 0);
+ }
+}
+
+// get the data
+void retrieveData() {
+ JSONObject json = loadJSONObject("http://time.jsontest.com/");
+ time = json.getString("time");
+}
+
+
+class Timer {
+
+ int savedTime;
+ boolean running = false;
+ int totalTime;
+
+ Timer(int tempTotalTime) {
+ totalTime = tempTotalTime;
+ }
+
+ void start() {
+ running = true;
+ savedTime = millis();
+ }
+
+ boolean isFinished() {
+ int passedTime = millis() - savedTime;
+ if (running && passedTime > totalTime) {
+ running = false;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
}
-In draw(), you can choose to display something to indicate the thread is running (when loading equals true).
+APIs
+
+
+ It’s a bit silly for me to call this section “APIs” given that most of this chapter is about data from APIs. Still, it’s worth taking a moment to pause and reflect. What makes something an API versus just some data you found, and what are some pitfalls you might run into when using an API?
+
+
+
+ As I've stated, an API (Application Programming Interface) is an interface through which one application can access the services of another. These can come in many forms. Openweathermap.org, as you saw earlier, is an API that offers its data in JSON, XML, and HTML formats. The key element that makes this service an API is exactly that offer; openweathermap.org's sole purpose in life is to offer you its data. And not just offer it, but allow you to query it for specific data in a specific format. Let's look at a short list of sample queries.
+
+
+
+ One thing to note about openweathermap.org is that it does not require that you tell the API any information about yourself. You simply send a request to a URL and get the data back. Other APIs, however, require you to sign up and obtain an access token. The New York Times API is one such example. Before you can make a request from Processing, you'll need to visit The New York Times Developer site and request an API key. Once you have that key, you can store it in your code as a string.
+
+// This is not a real key +String apiKey = "40e2es0b3ca44563f9c62aeded4431dc:12:51913116"; ++ You also need to know what the URL is for the API itself. This information is documented for you on the developer site, but here it is for simplicity:
+String url = "http://api.nytimes.com/svc/search/v2/articlesearch.json"; ++ Finally, you have to tell the API what it is you are looking for. This is done with a “query string,” a sequence of name value pairs describing the parameters of the query joined with an ampersand. This functions similarly to how you pass arguments to a function in Processing. If you wanted to search for the term "processing" from a search() function you might say:
+search("processing");
+
+ Here, the API acts as the function call, and you send it the arguments via the query string. Here is a simple example asking for a list of the oldest articles that contain the term "processing" (the oldest of which turns out to be May 12th, 1852).+// The name/value pairs that configure the API query are: (q,processing) and (sort,oldest) +String query = "?q=processing&sort=oldest"; ++ This isn't just guesswork. Figuring out how to put together a query string requires reading through the API's documentation. For The New York Times, it’s all outlined on the Times' developer website. Once you have your query you can join all the pieces together and pass it to loadJSONObject(). Here is a tiny example that simply displays the most recent headline. + +
+NYTimes API Query
+
-void draw() {
- if (loading) {
- // Draw something to indicate loading
- }
+void setup() {
+ size(200, 200);
+
+ String apiKey = "40e2ea0b3ca44563f9c62aeded0431dc:18:51513116";
+ String url = "http://api.nytimes.com/svc/search/v2/articlesearch.json";
+ String query = "?q=processing&sort=newest";
+
+ // Make the API query
+ // Here, I format the call to the API by joing the URL with the API key with the query string.
+ JSONObject json = loadJSONObject(url+query+"&api-key="+apiKey);
+
+ String headline = json.getJSONObject("response").getJSONArray("docs").
+ // Grabbing a single headline from the results.
+ getJSONObject(0).getJSONObject("headline").getString("main");
+ background(255);
+ fill(0);
+ text(headline, 10, 10, 180, 190);
}
+ Some APIs require a deeper level of authentication beyond an API access key. Twitter, for example, uses an authentication protocol known as “OAuth” to provide access to its data. Writing an OAuth application requires more than just passing a String into a request and is beyond the scope of this tutorial. However, in these cases, if you’re lucky, you can find a Processing library that handles all of the authentication for you. There are several APIs that can be used directly with Processing via a library, and you can find a list of them in the “Data / Protocols” section of the libraires reference page for some ideas. Temboo, for example, offers a Processing library that handles OAuth for you and provides direct access to many APIs (including Twitter) in Processing. With Temboo, you can write code that looks like:
+
+
+// Temboo acts as a go-between you and Twitter, so first you just authenticate with Temboo.
+TembooSession session = new TembooSession("ACCOUNT_NAME", "APP_NAME", "APP_KEY");
-Two examples that follow this methodology can be found under Topics --> Advanced Data in the Processing examples.
+Tweets tweets = new Tweets(session);
+// Then you can configure a query to send to Twitter itself and grab the results.
+tweets.setCredential("your-twitter-name");
+tweetsChoreo.setQuery("arugula");
+TweetsResultSet tweetsResults = tweets.run();
-While using the thread() function is a very simple way of getting an independent thread, it should be noted that it is somewhat limited. Being able to make a thread object is a great deal more powerful, and this can be done by extending the Java Thread class.
+JSONObject searchResults = parseJSONObject(tweetsResults.getResponse());
+JSONArray statuses = searchResults.getJSONArray("statuses");
+
+// Finally, you can search through the results and grab a tweet.
+JSONObject tweet = statuses.getJSONObject(0);
+String tweetText = tweet.getString("text");
+
|
This tutorial is for Processing version 3.0+. If you see any errors or have comments, please let us know. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. +The Long VersionIn order to use the Processing library to create our graphics while coding in Eclipse, we need to do a couple things. The first thing we need to do is import the Processing core as a library for our project, and the second is to set up our client class to take into consideration some of the processes (pun intended) that the Processing IDE does for us in the background. This guide is written for Processing 3+, with the intended audience of someone who has already downloaded Eclipse, but may have never used it before. If you are experienced with Java and Eclipse, you can jump to the bottom for a quick summary of the steps involved. Create a new ProjectFirst create a new project. It just needs to be a regular Java Project. File > New > Java Project -Let's name it 'Hello Processing'. Leave all the default settings and click Finish. +Let's name it 'Hello Processing'. Leave all the default settings and click Finish. Next, create a new class. File > New > Class -Let's name it 'UsingProcessing'. You can choose to include public static void main. -
Let's name it 'UsingProcessing'. You can choose to include public static void main. +
We should now have a new class that probably looks like this: public class UsingProcessing {
@@ -30,28 +30,28 @@ Now that we have our project and client class ready to go, we need to get the Processing core as a library. The idea of Libraries-One of the most important aspects of Java (or nearly any programming environment) is the idea of a Library. A Library is a collection of code that performs related tasks. They can be one class, or many. Some Libraries are so powerful and robust that they can almost be considered a "Language" themselves. When you combine the Processing library with the Processing IDE, you end up with something that most people refer to as the Processing 'Language', but technically, at it's heart, it's a collection of Java code. +One of the most important aspects of Java (or nearly any programming environment) is the idea of a Library. A Library is a collection of code that performs related tasks. They can be one class, or many. Some Libraries are so powerful and robust that they can almost be considered a "Language" themselves. When you combine the Processing library with the Processing IDE, you end up with something that most people refer to as the Processing 'Language', but technically, at it's heart, it's a collection of Java code. To make it work, the Processing IDE does a lot of stuff for us in the background 'Java' environment in order to make it really easy for us as programmers to create sketches. However, to make full use of all the Java awesomeness at our disposal, it's helpful to use a more robust IDE, which is why we are jumping into Eclipse. So let's get Eclipse to use Processing as a Library. Import the Processing CoreIn order for Eclipse to see the code that makes up Processing, we need to import it into our project. File > Import > General > File System Click next. On Windows, click "Browse..." and select the Processing jar files inside PATH_TO_PROCESSING/core/library/. On OS X, do not use the "Browse..." button. Instead, use the "From directory:" field to manually enter the path to Processing's jar files, which is typically /Applications/Processing 3.app/Contents/Java/core/library/. At minimum, select the "core.jar" file inside the "library" folder. -
A .jar file is a compiled collection of Java code. The core.jar is the core of the Processing libraries, it has all the code that does the stuff that we are used to doing in Processing, like drawing shapes. Once we have it, we can make use of all the normal Processing commands that are found on the reference page. Click Finish. If you look at the Package Explorer, you'll notice that there is a new file in our project, called 'core.jar'. -
Now that we have the file in our project, we need to tell Eclipse that this file is part of the code base that is used to build, or compile and run, this project. Do this by right clicking on the core.jar, going to Build Path, and then Add to Build Path -
You'll notice the project will expand to have a new section called 'Referenced Libraries', where there is a new core.jar file. You can expand this to see a hierarchy of it's contents, if you are really interested. -
We are finally ready to set up our client class (the class with our main function, where the program starts), to run the project like a Processing sketch. +
We are finally ready to set up our client class (the class with our main function, where the program starts), to run the project like a Processing sketch. Setting up the Client Class-A Processing window is a special type of Java program called a PApplet. This is technically a Java Class, which has its own main function (or method) and does all kinds of fancy stuff that we don't need to worry about to create a new window and draw graphics onto it. In order for us to make use of the PApplet class, we want our program to BE a PApplet. To make this happen, we use the keyword extends in our class declaration. This will allow our class to 'inherit' all the PApplet class' functions and variables. Change the first line of code to be: +A Processing window is a special type of Java program called a PApplet. This is technically a Java Class, which has its own main function (or method) and does all kinds of fancy stuff that we don't need to worry about to create a new window and draw graphics onto it. In order for us to make use of the PApplet class, we want our program to BE a PApplet. To make this happen, we use the keyword extends in our class declaration. This will allow our class to 'inherit' all the PApplet class' functions and variables. Change the first line of code to be: public class UsingProcessing extends PApplet{
You'll notice this will give you an error. This occurs because, although we have included the core.jar to our project, we still have to link to the library in the code. We do this by using an import statement, at the top of the Java file. Anytime we are going to reference a function, variable, or class outside of the Java file we are writing in, we need to tell Java where it is by importing it. Eclipse will help you by suggesting to do this. Hover over the error (where it's underlined in red) and choose from the options "Import 'PApplet' (processing.core)". -
This will auto add a new line of code to the top of the file: The next step is to simply start a PApplet application, and tell it to use this class, Add the following line to the main function (method), and if the TODO comment is still there, you can delete/replace it. @@ -71,11 +71,11 @@Setting up the Client Class} -NOTE: If your class is part of a package other than the default package, you must call PApplet's main using the package name as well, like this: +NOTE: If your class is part of a package other than the default package, you must call PApplet's main using the package name as well, like this: PApplet.main("packageName.ClassName");
At this point, you can run the program. If Eclipse asks, choose to run the program as a Java Application. Processing no longer extends the Applet class, so you can't run it as an Applet! +At this point, you can run the program. If Eclipse asks, choose to run the program as a Java Application. Processing no longer extends the Applet class, so you can't run it as an Applet! This will run a PApplet as if you had run an empty sketch. You will get a new 100x100 window open with a blank canvas! Now we are ready to add the final touches to be ready to program like we were before. After main(), add three new functions:
@@ -127,7 +127,7 @@
Setting up the Client Class}We did it! We have a Processing application running from Eclipse, and now we can take advantage of all the powerful tools that Eclipse has to offer. From here, you can develop your processing sketch to your heart's content. -The Short Version+The Short VersionThe quick break down of what we did here:
The Short Version
Processing in Eclipse with Multiple ClassesTake a look at this example Processing sketch. The example is object-oriented and contains a class called "Stripe." In Processing, all classes are treated as "inner classes," meaning they are not individual entities unto themselves, but rather are classes inside of the larger PApplet. This is why you can do anything you can do in a PApplet inside of the Stripe class. You can draw onto the window calling rect() and access the PApplet variables such as width and height. To get this example working in Eclipse, it's perfectly reasonable to just copy it in as is and include the Stripe class code below setup() and draw() inside the parent PApplet class. However, the inner class methodology can quickly become unwieldy in the case of larger applications with lots and lots of classes. import processing.core.*; @@ -220,7 +221,22 @@ and if you are in another class and have to refer to the "parent" PApplet: int pink = parent.color(255,200,200);- + Globally Available Functions+Pretty much anything you can find in the reference can be used in Eclipse the same way, with some concesssions to be made for proper Java syntax. For example, any of the mouse Event functions, including mouseClicked(), mousePressed(), mouseDragged(), and mouseWheel(). +These can be added in the exact same way as setup(), and draw(), just by adding the keyword 'public' to the declaration. So, looking at the reference example of mousePressed(): +void mousePressed() {
+ if (value == 0) {
+ ...
+}
+Would be declared instead as: +public void mousePressed() {
+ if (value == 0) {
+ ...
+}
+That's all there is to it! The same process works for all the mouse, keyboard, and other event based functions. +Note, however, that these functions are inherited from PApplet, thus you will only be able to use them in your client class, and not in any other object classes. +Exporting in Eclipse+You can export a project from eclipse the same way you export any project in Eclipse. For more information, visit Eclipse's documentation. How to export a runnable .jar in Eclipse. This tutorial is for Processing version 3.0+. If you see any errors or have comments, please let us know. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. |
With any luck, the main Processing window will now be visible. Everyone's setup is different, so if the program didn't start, or you're otherwise stuck, visit the troubleshooting page for possible solutions.
+With any luck, the main Processing window will now be visible. Everyone's setup is different, so if the program didn't start, or you're otherwise stuck, visit the troubleshooting page for possible solutions.
diff --git a/content/static/tutorials/imgs/video.png b/content/static/tutorials/imgs/video.png new file mode 100644 index 000000000..4a408066c Binary files /dev/null and b/content/static/tutorials/imgs/video.png differ diff --git a/content/static/tutorials/index.html b/content/static/tutorials/index.html index 4d6a18f2a..7434e5bbb 100644 --- a/content/static/tutorials/index.html +++ b/content/static/tutorials/index.html @@ -286,17 +286,29 @@
-
Anatomy of a Program
- by J David Eisenberg
How do you analyze a problem and break it down into steps that the computer can do?
+
+
Video
+ by Daniel Shiffman
How to display live and recorded video
Level: Advanced
+
Anatomy of a Program
+ by J David Eisenberg
How do you analyze a problem and break it down into steps that the computer can do?
+Level: Advanced
+false
false
+ - To work with fonts different than the default, more functions are needed to prepare a font to be used with Processing. The createFont() function is used to convert a TrueType font (.ttf) or OpenType font (.otf) so that is can display through text(). The textFont() function is used to define the current font to display. Any compatible font installed on the computer running Processing or stored in the sketch’s data folder may be used. The following short program is used to print the list of the available installed fonts to the console: + To work with fonts different than the default, more functions are needed to prepare a font to be used with Processing. The createFont() function is used to convert a TrueType font (.ttf) or OpenType font (.otf) so that it can display through text(). The textFont() function is used to define the current font to display. Any compatible font installed on the computer running Processing or stored in the sketch’s data folder may be used. The following short program is used to print the list of the available installed fonts to the console:
diff --git a/content/static/tutorials/video/imgs/fig_16_01_capture.png b/content/static/tutorials/video/imgs/fig_16_01_capture.png new file mode 100755 index 000000000..09bfc22ce Binary files /dev/null and b/content/static/tutorials/video/imgs/fig_16_01_capture.png differ diff --git a/content/static/tutorials/video/imgs/fig_16_02_tintvideo.png b/content/static/tutorials/video/imgs/fig_16_02_tintvideo.png new file mode 100755 index 000000000..aa8c0cc35 Binary files /dev/null and b/content/static/tutorials/video/imgs/fig_16_02_tintvideo.png differ diff --git a/content/static/tutorials/video/imgs/fig_16_03_flashlight.png b/content/static/tutorials/video/imgs/fig_16_03_flashlight.png new file mode 100755 index 000000000..a395fa12c Binary files /dev/null and b/content/static/tutorials/video/imgs/fig_16_03_flashlight.png differ diff --git a/content/static/tutorials/video/imgs/fig_16_04_blankgrid.png b/content/static/tutorials/video/imgs/fig_16_04_blankgrid.png new file mode 100755 index 000000000..75c47bd1d Binary files /dev/null and b/content/static/tutorials/video/imgs/fig_16_04_blankgrid.png differ diff --git a/content/static/tutorials/video/imgs/fig_16_05_pixelated.png b/content/static/tutorials/video/imgs/fig_16_05_pixelated.png new file mode 100755 index 000000000..6e9c6b356 Binary files /dev/null and b/content/static/tutorials/video/imgs/fig_16_05_pixelated.png differ diff --git a/content/static/tutorials/video/imgs/fig_16_06_mirror.png b/content/static/tutorials/video/imgs/fig_16_06_mirror.png new file mode 100755 index 000000000..3af852ae3 Binary files /dev/null and b/content/static/tutorials/video/imgs/fig_16_06_mirror.png differ diff --git a/content/static/tutorials/video/imgs/fig_16_07_blank_scribble.png b/content/static/tutorials/video/imgs/fig_16_07_blank_scribble.png new file mode 100755 index 000000000..72fc30783 Binary files /dev/null and b/content/static/tutorials/video/imgs/fig_16_07_blank_scribble.png differ diff --git a/content/static/tutorials/video/imgs/fig_16_08_scribblermirror.png b/content/static/tutorials/video/imgs/fig_16_08_scribblermirror.png new file mode 100755 index 000000000..ecc48f703 Binary files /dev/null and b/content/static/tutorials/video/imgs/fig_16_08_scribblermirror.png differ diff --git a/content/static/tutorials/video/index.html b/content/static/tutorials/video/index.html new file mode 100644 index 000000000..22ccf759b --- /dev/null +++ b/content/static/tutorials/video/index.html @@ -0,0 +1,575 @@ +
|
+
+ + This tutorial is from the book Learning Processing, 2nd Edition by Daniel Shiffman, published by Morgan Kaufmann, © 2015 Elsevier Inc. All rights reserved. If you see any errors or have comments, please let us know. + + +Video+Daniel Shiffman+ +Live Video+ +
+Now that you’ve explored static images in Processing, you are ready to move on to moving images, specifically from a live camera (and later, from a recorded movie). I’ll begin by walking through the basic steps of importing the video library and using the Capture class to display live video.
+ +import processing.video.*; ++Using the “Import Library” menu option does nothing other than automatically insert that line into your code, so manual typing is entirely equivalent. + + +Step 2. Declare a Capture object. + +You’ve recently seen how to create objects from classes built into the Processing language such as PShape and PImage. Both of these classes, it should be noted, are part of the processing.core library and, therefore,no import statement were required. The processing.video library has two useful classes inside of it — Capture, for live video, and Movie, for recorded video. In this step, I’ll be declaring a Capture object. + +Capture video; ++ +Step 3. Initialize the Capture object. + +The Capture object “video” is just like any other object — to construct an object, you use the new operator followed by the constructor. With a Capture object, this code typically appears in setup(). + +video = new Capture(); ++The above line of code is missing the appropriate arguments for the constructor. Remember, this is not a class you wrote yourself so there is no way to know what is required between the parentheses without consulting the online reference. + +The reference will show there are several ways to call the Capture constructor. A typical way to call the constructor is with three arguments: +
+void setup() {
+ video = new Capture(this, 320, 240);
+}
+
+Let’s walk through the arguments used in the Capture constructor.
+
+
+ +printArray(Capture.list()); ++You can use the text of these configurations to create a Capture object. On a Mac with a built-in camera,for example, this might look like: + +video = new Capture(this, "name=FaceTime HD Camera (Built-in),size=320x240,fps=30"); ++Capture.list() actually gives you an array so you can also simply refer to the index of the configuration you want. + +video = new Capture(this, Capture.list()[0]); ++ +Step 4. Start the capture process. + +Once the camera is ready, it’s up to you to tell Processing to start capturing images. +
+void setup() {
+ video = new Capture(this, 320, 240);
+ video.start();
+}
+
+In almost every case you want to begin capturing right in setup(). Nevertheless, start() is its own method, and you do have the option of, say, not starting capturing until some other time (such as when a button is pressed, etc.)
++ +Step 5. Read the image from the camera. + +There are two strategies for reading frames from the camera. I will briefly look at both and choose one forthe remainder of the examples in this chapter. Both strategies, however, operate under the same fundamental principle: I only want to read an image from the camera when a new frame is available to be read. + + +In order to check if an image is available, you use the function available(), which returns true or false depending on whether something is there. If it is there, the function read() is called and the frame from the camera is read into memory. You can do this over and over again in the draw() loop, always checking to see if a new image is free to be read. +
+void draw() {
+ if (video.available()) {
+ video.read();
+ }
+}
+
+The second strategy, the “event” approach, requires a function that executes any time a certain event — in this case a camera event — occurs. The function mousePressed() is executed whenever the mouse is pressed. With video, you have the option to implement the function captureEvent(), which is invoked any time a capture event occurs, that is, a new frame is available from the camera. These event functions (mousePressed(), keyPressed(), captureEvent(), etc.) aresometimes referred to as a “callback.” And as a brief aside, if you’re following closely, this is where this fits in. The Capture object, video, knows to notify this sketch by invoking captureEvent() because you passed it a reference to this sketch when creating the Capture object video.
++captureEvent() is a function and therefore needs to live in its own block, outside of setup() and draw(). +
+void captureEvent(Capture video) {
+ video.read();
+}
+
+You might notice something odd about captureEvent(). It includes an argument of type Capture in its definition. This might seem redundant to you; after all, in this example I already have a global variable video. Nevertheless in the case where you might have more than one capture device, the same event function can be used for both and the video library will make sure that the correct Capture object is passed in to captureEvent().
++To summarize, I want to call the function read() whenever there is something to read, and I can do so by either checking manually using available() within draw() or allowing a callback to handle it for you — captureEvent(). This allows sketches to operate more efficientlyby separating out the logic for reading from the camera from the main animation loop. + +Step 6. Display the video image. + +This is, without a doubt, the easiest part. You can think of a Capture object as a PImage that changes over time, and, in fact, a Capture object can be utilized in an identical manner as a PImage object. + +
++image(video, 0, 0); ++All of this is put together in the following code: +
+// Step 1. Import the video library.
+import processing.video.*;
+
+//Step 2. Declare a capture object.
+Capture video;
+
+// Step 5. Read from the camera when a new image is available!
+void captureEvent(Capture video) {
+ video.read();
+}
+
+void setup() {
+ size(320, 240);
+
+ // Step 3. Initialize Capture object.
+ video = new Capture(this, 320, 240);
+
+ // Step 4. Start the capturing process.
+ video.start();
+}
+
+// Step 6. Display the image.
+void draw() {
+image(video, 0, 0);
+}
+
+Again, anything you can do with a PImage (resize, tint, move, etc.) you can do with a Capture object. As long as you read() from that object, the video image will update as you manipulate it. See the following example:
++
+
+import processing.video.*;
+
+Capture video;
+
+void setup() {
+ size(320, 240);
+ video = new Capture(this, 320, 240);
+ video.start();
+}
+
+void captureEvent(Capture video) {
+ video.read();
+}
+
+void draw() {
+ background(255);
+ tint(mouseX, mouseY, 255);
+ translate(width/2, height/2);
+ imageMode(CENTER);
+ rotate(PI/4);
+ image(video, 0, 0, mouseX, mouseY);
+}
+
+Note that a video image can be tinted just like a PImage. It can also be moved, rotated, and sized just like a PImage. Following is the “adjusting brightness” example with a video image:
++
+
+// Step 1. Import the video library
+import processing.video.*;
+
+// Step 2. Declare a Capture object
+Capture video;
+
+void setup() {
+ size(320, 240);
+
+ // Step 3. Initialize Capture object via Constructor
+ video = new Capture(this, 320, 240);
+ video.start();
+}
+
+// An event for when a new frame is available
+void captureEvent(Capture video) {
+ // Step 4. Read the image from the camera.
+ video.read();
+}
+void draw() {
+ loadPixels();
+ video.loadPixels();
+
+ for (int x = 0; x < video.width; x++) {
+ for (int y = 0; y < video.height; y++) {
+ // Calculate the 1D location from a 2D grid
+ int loc = x + y * video.width;
+
+ // Get the red, green, blue values from a pixel
+ float r = red (video.pixels[loc]);
+ float g = green(video.pixels[loc]);
+ float b = blue (video.pixels[loc]);
+
+ // Calculate an amount to change brightness based on proximity to the mouse
+ float d = dist(x, y, mouseX, mouseY);
+ float adjustbrightness = map(d, 0, 100, 4, 0);
+ r *= adjustbrightness;
+ g *= adjustbrightness;
+ b *= adjustbrightness;
+
+ // Constrain RGB to make sure they are within 0-255 color range
+ r = constrain(r, 0, 255);
+ g = constrain(g, 0, 255);
+ b = constrain(b, 0, 255);
+
+ // Make a new color and set pixel in the window
+ color c = color(r, g, b);
+ pixels[loc] = c;
+ }
+ }
+
+ updatePixels();
+}
+
+
+
+Recorded video+
+Displaying recorded video follows much of the same structure as live video. Processing’s video library accepts most video file formats; for specifics, visit the Movie reference. +Movie movie; ++ +Step 2. Initialize Movie object. + +movie = new Movie(this, "testmovie.mov"); ++The only necessary arguments are this and the movie’s filename enclosed in quotes. The movie file should be stored in the sketch’s data directory. + + +Step 3. Start movie playing. + +There are two options, play(), which plays the movie once, or loop(), which loops it continuously. + +movie.loop(); ++ +Step 4. Read frame from movie. + +Again, this is identical to capture. You can either check to see if a new frame is available, or use a callback function. +
+void draw() {
+ if (movie.available()) {
+ movie.read();
+ }
+}
+
+Or:+
+void movieEvent(Movie movie) {
+ movie.read();
+}
+
+
+Step 5. Display the movie.+ +image(movie, 0, 0); ++The following code shows the program all together: +
+import processing.video.*;
+
+// Step 1. Declare a Movie object.
+Movie movie;
+
+void setup() {
+ size(320, 240);
+
+ // Step 2. Initialize Movie object. The file "testmovie.mov" should live in the data folder.
+ movie = new Movie(this, "testmovie.mov");
+
+ // Step 3. Start playing movie. To play just once play() can be used instead.
+ movie.loop();
+}
+
+// Step 4. Read new frames from the movie.
+void movieEvent(Movie movie) {
+ movie.read();
+}
+
+// Step 5. Display movie.
+void draw() {
+ image(movie, 0, 0);
+}
+
+
+Although Processing is by no means the most sophisticated environment for displaying and manipulating recorded video, there are some more advanced features available in the video library. There are functions for obtaining the duration (length measured in seconds) of a video, for speeding it up and slowing it down, and for jumping to a specific point in the video (among others). If you find that performance is sluggish and the video playback is choppy, I would suggest trying the P2D or P3D renderers.
++Following is an example that makes use of jump() (jump to a specific point in the video) and duration() (returns the length of movie in seconds). In this example, if mouseX equals 0, the video jumps to the beginning. If mouseX equals width, it jumps to the end. Any other value is in between. The jump() function allows you to jump immediately to a point of time within the video. duration() returns the total length of the movie in seconds. + +
+import processing.video.*;
+
+Movie movie;
+
+void setup() {
+ size(200, 200);
+ background(0);
+ movie = new Movie(this, "testmovie.mov");
+}
+
+void movieEvent(Movie movie) {
+ movie.read();
+}
+
+void draw() {
+ // Ratio of mouse X over width
+ float ratio = mouseX / (float) width;
+
+ movie.jump(ratio * movie.duration());
+
+ image(movie, 0, 0);
+}
+
+
+
+Software mirrors+
+With small video cameras attached to more and more personal computers, developing software that manipulates an image in real-time is becoming increasingly popular. These types of applications are sometimes referred to as “mirrors,” as they provide a digital reflection of a viewer’s image. Processing’s extensive library of functions for graphics and its ability to capture from a camera in real-time make it an excellent environment for prototyping and experimenting with software mirrors.
+
+// Size of each cell in the grid, ratio of window size to video size
+int videoScale = 8;
+// Number of columns and rows in the system
+int cols, rows;
+
+void setup() {
+ size(640, 480);
+ // Initialize columns and rows
+ cols = width/videoScale;
+ rows = height/videoScale;
+}
+
+void draw() {
+ // Begin loop for columns
+ for (int i = 0; i < cols; i++) {
+ // Begin loop for rows
+ for (int j = 0; j < rows; j++) {
+ // Scaling up to draw a rectangle at (x,y)
+ int x = i*videoScale;
+ int y = j*videoScale;
+ fill(255);
+ stroke(0);
+ rect(x, y, videoScale, videoScale);
+ }
+ }
+}
+
+Knowing that I want to have squares eight pixels wide by eight pixels high, I can calculate the number of columns as the width divided by eight and the number of rows as the height divided by eight.
+
+ +For every square at column i and row j, I look up the color at pixel (i, j) in the video image and color it accordingly. See the following example with the new parts in bold: +
+import processing.video.*;
+
+// Size of each cell in the grid, ratio of window size to video size
+int videoScale = 8;
+// Number of columns and rows in the system
+int cols, rows;
+// Variable to hold onto Capture object
+Capture video;
+
+void setup() {
+ size(640, 480);
+ // Initialize columns and rows
+ cols = width/videoScale;
+ rows = height/videoScale;
+ background(0);
+ video = new Capture(this, cols, rows);
+ video.start()
+}
+
+// Read image from the camera
+void captureEvent(Capture video) {
+ video.read();
+}
+
+void draw() {
+ video.loadPixels();
+ // Begin loop for columns
+ for (int i = 0; i < cols; i++) {
+ // Begin loop for rows
+ for (int j = 0; j < rows; j++) {
+ // Where are you, pixel-wise?
+ int x = i*videoScale;
+ int y = j*videoScale;
+ color c = video.pixels[i + j*video.width];
+ fill(c);
+ stroke(0);
+ rect(x, y, videoScale, videoScale);
+ }
+ }
+}
+
+As you can see, expanding the simple grid system to include colors from video only requires a few additions. I have to declare and initialize the Capture object, read from it, and pull colors from the pixel array.+
+Less literal mappings of pixel colors to shapes in the grid can also be applied. In the following example, only the colors black and white are used. Squares are larger where brighter pixels in the video appear, and smaller for darker pixels.+
+// Each pixel from the video source is drawn as
+// a rectangle with size based on brightness.
+
+import processing.video.*;
+// Size of each cell in the grid
+int videoScale = 10;
+// Number of columns and rows in the system
+int cols, rows;
+// Variable for capture device
+Capture video;
+
+void setup() {
+ size(640, 480);
+ // Initialize columns and rows
+ cols = width / videoScale;
+ rows = height / videoScale;
+ // Construct the Capture object
+ video = new Capture(this, cols, rows);
+ video.start();
+}
+
+void captureEvent(Capture video) {
+ video.read();
+}
+
+void draw() {
+ background(0);
+ video.loadPixels();
+ // Begin loop for columns
+ for (int i = 0; i < cols; i++) {
+ // Begin loop for rows
+ for (int j = 0; j < rows; j++) {
+ // Where are you, pixel-wise?
+ int x = i*videoScale;
+ int y = j*videoScale;
+
+ // Reverse the column to mirro the image.
+ int loc = (video.width - i - 1) + j * video.width;
+
+ color c = video.pixels[loc];
+ // A rectangle's size is calculated as a function of the pixel’s brightness.
+ // A bright pixel is a large rectangle, and a dark pixel is a small one.
+ float sz = (brightness(c)/255) * videoScale;
+
+ rectMode(CENTER);
+ fill(255);
+ noStroke();
+ rect(x + videoScale/2, y + videoScale/2, sz, sz);
+ }
+ }
+}
+
+It’s often useful to think of developing software mirrors in two steps. This will also help you think beyondthe more obvious mapping of pixels to shapes on a grid.
++Step 1. Develop an interesting pattern that covers an entire window. + +Step 2. Use a video’s pixels as a look-up table for coloring that pattern. + +Say for Step 1, I write a program that scribbles a random line around the window. Here is my algorithm, written in pseudocode. +
+
+
+// Two global variables
+float x;
+float y;
+
+void setup() {
+ size(320, 240);
+ background(255);
+ // Start x and y in the center
+ x = width/2;
+ y = height/2;
+}
+
+void draw() {
+ float newx = constrain(x + random(-20, 20), 0, width);
+ float newy = constrain(y + random(-20, 20), 0, height);
+
+ // Line from (x,y) to the (newx,newy)
+ stroke(0);
+ strokeWeight(4);
+ line(x, y, newx, newy);
+
+ x = newx;
+ y = newy;
+}
+
+Now that I have finished the pattern generating sketch, I can change stroke() to set a color according to the video image. Note again the new lines of code added in bold in the following code:
++
+
+import processing.video.*;
+// Two global variables
+float x;
+float y;
+
+// Variable to hold onto Capture object.
+Capture video;
+
+void setup() {
+ size(320, 240);
+ background(255);
+ // Start x and y in the center
+ x = width/2;
+ y = height/2;
+ // Start the capture process
+ video = new Capture(this, width, height);
+ video.start();
+}
+
+void captureEvent(Capture video) {
+ // Read image from the camera
+ video.read();
+}
+
+void draw() {
+ video.loadPixels();
+ float newx = constrain(x + random(-20, 20), 0, width);
+ float newy = constrain(y + random(-20, 20), 0, height-1);
+
+ // Find the midpoint of the line
+ int midx = int((newx + x) / 2);
+ int midy = int((newy + y) / 2);
+ // Pick the color from the video, reversing x
+ color c = video.pixels[(width-1-midx) + midy*video.width];
+
+ // Draw a line from (x,y) to (newx,newy)
+ stroke(c);
+ strokeWeight(4);
+ line(x, y, newx, newy);
+
+ // Save (newx,newy) in (x,y)
+ x = newx;
+ y = newy;
+}
+
+
+
+ |
+
-
-
-
-
-
-
- Earlier releases have been removed because we can only support the current versions of the software. To update old code, read the changes page. Changes for each release can be found in revisions.txt. If you have problems with the current release, please file a bug so that we can fix it. Older releases can also be built from the source. Read More about the releases and their numbering. To use Android Mode, Processing 3 or later is required.
-The revisions cover incremental changes between releases, and are especially important to read for pre-releases.
-mailed returned " . $result . "
"); -//echo("ErrorInfo is " . $mail->ErrorInfo . "
"); - -exit; - -?> \ No newline at end of file diff --git a/download/_helpers.php b/download/_helpers.php deleted file mode 100644 index dc5c90325..000000000 --- a/download/_helpers.php +++ /dev/null @@ -1,24 +0,0 @@ - \ No newline at end of file diff --git a/download/_js/donate.js b/download/_js/donate.js deleted file mode 100644 index b847b5ad9..000000000 --- a/download/_js/donate.js +++ /dev/null @@ -1,54 +0,0 @@ -$(function(){ - - var $donateForm = $('#donateForm') - var $submit = $donateForm.find('input[type="submit"]') - var stripe = true - - // if($('input[name=type]:checked').val() != 'stripe'){ - // stripe = false - // $('.ccInfo').hide() - // } - - $('input[name=type]').on('change', function(){ - if($(this).val()=='stripe'){ - stripe = true - $('.ccInfo').show() - } else if($(this).val()=='paypal'){ - stripe = false - $('.ccInfo').hide() - } - }) - - var stripeResponseHandler = function(status, response) { - if (response.error) { - $('.messages').html(response.error.message) - $submit.prop('disabled', false).val('Complete Donation') - } else { - var token = response['id'] - $donateForm.append('') - $donateForm.get(0).submit() - } - } - - // $donateForm.validate() - $donateForm.on('submit',function(){ - $submit.prop('disabled', true).val('Processing...'); - - if(stripe){ - Stripe.createToken({ - name: $('.first-name').val() + ' ' + $('.last-name').val(), - number: $('.card-number').val(), - cvc: $('.card-cvc').val(), - exp_month: $('.card-expiry-month').val(), - exp_year: $('.card-expiry-year').val() - }, stripeResponseHandler); - - return false; - } - - if(!stripe){ - - } - }) - -}) diff --git a/download/_js/jquery.validate.min.js b/download/_js/jquery.validate.min.js deleted file mode 100755 index cc0414e65..000000000 --- a/download/_js/jquery.validate.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery Validation Plugin - v1.11.0 - 2/4/2013 -* https://github.com/jzaefferer/jquery-validation -* Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */ -(function(e){e.extend(e.fn,{validate:function(t){if(!this.length){t&&t.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.");return}var n=e.data(this[0],"validator");return n?n:(this.attr("novalidate","novalidate"),n=new e.validator(t,this[0]),e.data(this[0],"validator",n),n.settings.onsubmit&&(this.validateDelegate(":submit","click",function(t){n.settings.submitHandler&&(n.submitButton=t.target),e(t.target).hasClass("cancel")&&(n.cancelSubmit=!0)}),this.submit(function(t){function r(){var r;return n.settings.submitHandler?(n.submitButton&&(r=e("").attr("name",n.submitButton.name).val(n.submitButton.value).appendTo(n.currentForm)),n.settings.submitHandler.call(n,n.currentForm,t),n.submitButton&&r.remove(),!1):!0}return n.settings.debug&&t.preventDefault(),n.cancelSubmit?(n.cancelSubmit=!1,r()):n.form()?n.pendingRequest?(n.formSubmitted=!0,!1):r():(n.focusInvalid(),!1)})),n)},valid:function(){if(e(this[0]).is("form"))return this.validate().form();var t=!0,n=e(this[0].form).validate();return this.each(function(){t&=n.element(this)}),t},removeAttrs:function(t){var n={},r=this;return e.each(t.split(/\s/),function(e,t){n[t]=r.attr(t),r.removeAttr(t)}),n},rules:function(t,n){var r=this[0];if(t){var i=e.data(r.form,"validator").settings,s=i.rules,o=e.validator.staticRules(r);switch(t){case"add":e.extend(o,e.validator.normalizeRule(n)),s[r.name]=o,n.messages&&(i.messages[r.name]=e.extend(i.messages[r.name],n.messages));break;case"remove":if(!n)return delete s[r.name],o;var u={};return e.each(n.split(/\s/),function(e,t){u[t]=o[t],delete o[t]}),u}}var a=e.validator.normalizeRules(e.extend({},e.validator.classRules(r),e.validator.attributeRules(r),e.validator.dataRules(r),e.validator.staticRules(r)),r);if(a.required){var f=a.required;delete a.required,a=e.extend({required:f},a)}return a}}),e.extend(e.expr[":"],{blank:function(t){return!e.trim(""+t.value)},filled:function(t){return!!e.trim(""+t.value)},unchecked:function(e){return!e.checked}}),e.validator=function(t,n){this.settings=e.extend(!0,{},e.validator.defaults,t),this.currentForm=n,this.init()},e.validator.format=function(t,n){return arguments.length===1?function(){var n=e.makeArray(arguments);return n.unshift(t),e.validator.format.apply(this,n)}:(arguments.length>2&&n.constructor!==Array&&(n=e.makeArray(arguments).slice(1)),n.constructor!==Array&&(n=[n]),e.each(n,function(e,n){t=t.replace(new RegExp("\\{"+e+"\\}","g"),function(){return n})}),t)},e.extend(e.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:e([]),errorLabelContainer:e([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(e,t){this.lastActive=e,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,e,this.settings.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(e)).hide())},onfocusout:function(e,t){!this.checkable(e)&&(e.name in this.submitted||!this.optional(e))&&this.element(e)},onkeyup:function(e,t){if(t.which===9&&this.elementValue(e)==="")return;(e.name in this.submitted||e===this.lastElement)&&this.element(e)},onclick:function(e,t){e.name in this.submitted?this.element(e):e.parentNode.name in this.submitted&&this.element(e.parentNode)},highlight:function(t,n,r){t.type==="radio"?this.findByName(t.name).addClass(n).removeClass(r):e(t).addClass(n).removeClass(r)},unhighlight:function(t,n,r){t.type==="radio"?this.findByName(t.name).removeClass(n).addClass(r):e(t).removeClass(n).addClass(r)}},setDefaults:function(t){e.extend(e.validator.defaults,t)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:e.validator.format("Please enter no more than {0} characters."),minlength:e.validator.format("Please enter at least {0} characters."),rangelength:e.validator.format("Please enter a value between {0} and {1} characters long."),range:e.validator.format("Please enter a value between {0} and {1}."),max:e.validator.format("Please enter a value less than or equal to {0}."),min:e.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function r(t){var n=e.data(this[0].form,"validator"),r="on"+t.type.replace(/^validate/,"");n.settings[r]&&n.settings[r].call(n,this[0],t)}this.labelContainer=e(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||e(this.currentForm),this.containers=e(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var t=this.groups={};e.each(this.settings.groups,function(n,r){typeof r=="string"&&(r=r.split(/\s/)),e.each(r,function(e,r){t[r]=n})});var n=this.settings.rules;e.each(n,function(t,r){n[t]=e.validator.normalizeRule(r)}),e(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",r).validateDelegate("[type='radio'], [type='checkbox'], select, option","click",r),this.settings.invalidHandler&&e(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),e.extend(this.submitted,this.errorMap),this.invalid=e.extend({},this.errorMap),this.valid()||e(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var e=0,t=this.currentElements=this.elements();t[e];e++)this.check(t[e]);return this.valid()},element:function(t){t=this.validationTargetFor(this.clean(t)),this.lastElement=t,this.prepareElement(t),this.currentElements=e(t);var n=this.check(t)!==!1;return n?delete this.invalid[t.name]:this.invalid[t.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),n},showErrors:function(t){if(t){e.extend(this.errorMap,t),this.errorList=[];for(var n in t)this.errorList.push({message:t[n],element:this.findByName(n)[0]});this.successList=e.grep(this.successList,function(e){return!(e.name in t)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){e.fn.resetForm&&e(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(e){var t=0;for(var n in e)t++;return t},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return this.size()===0},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{e(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(t){}},findLastActive:function(){var t=this.lastActive;return t&&e.grep(this.errorList,function(e){return e.element.name===t.name}).length===1&&t},elements:function(){var t=this,n={};return e(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&t.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in n||!t.objectLength(e(this).rules())?!1:(n[this.name]=!0,!0)})},clean:function(t){return e(t)[0]},errors:function(){var t=this.settings.errorClass.replace(" ",".");return e(this.settings.errorElement+"."+t,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=e([]),this.toHide=e([]),this.currentElements=e([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(e){this.reset(),this.toHide=this.errorsFor(e)},elementValue:function(t){var n=e(t).attr("type"),r=e(t).val();return n==="radio"||n==="checkbox"?e("input[name='"+e(t).attr("name")+"']:checked").val():typeof r=="string"?r.replace(/\r/g,""):r},check:function(t){t=this.validationTargetFor(this.clean(t));var n=e(t).rules(),r=!1,i=this.elementValue(t),s;for(var o in n){var u={method:o,parameters:n[o]};try{s=e.validator.methods[o].call(this,i,t,u.parameters);if(s==="dependency-mismatch"){r=!0;continue}r=!1;if(s==="pending"){this.toHide=this.toHide.not(this.errorsFor(t));return}if(!s)return this.formatAndAdd(t,u),!1}catch(a){throw this.settings.debug&&window.console&&console.log("Exception occured when checking element "+t.id+", check the '"+u.method+"' method.",a),a}}if(r)return;return this.objectLength(n)&&this.successList.push(t),!0},customDataMessage:function(t,n){return e(t).data("msg-"+n.toLowerCase())||t.attributes&&e(t).attr("data-msg-"+n.toLowerCase())},customMessage:function(e,t){var n=this.settings.messages[e];return n&&(n.constructor===String?n:n[t])},findDefined:function(){for(var e=0;eProcessing is open source, free software. All donations fund the Processing Foundation, a nonprofit organization devoted to advancing the role of programming within the visual arts through developing Processing.
- - - - - - - - -' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "
\n"; - } - } - $this->ErrorInfo = $msg; - } - - /** - * Returns the proper RFC 822 formatted date. - * @access public - * @return string - * @static - */ - public static function RFCDate() { - $tz = date('Z'); - $tzs = ($tz < 0) ? '-' : '+'; - $tz = abs($tz); - $tz = (int)($tz/3600)*100 + ($tz%3600)/60; - $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz); - - return $result; - } - - /** - * Returns the server hostname or 'localhost.localdomain' if unknown. - * @access protected - * @return string - */ - protected function ServerHostname() { - if (!empty($this->Hostname)) { - $result = $this->Hostname; - } elseif (isset($_SERVER['SERVER_NAME'])) { - $result = $_SERVER['SERVER_NAME']; - } else { - $result = 'localhost.localdomain'; - } - - return $result; - } - - /** - * Returns a message in the appropriate language. - * @access protected - * @param string $key - * @return string - */ - protected function Lang($key) { - if(count($this->language) < 1) { - $this->SetLanguage('en'); // set the default language - } - - if(isset($this->language[$key])) { - return $this->language[$key]; - } else { - return 'Language string failed to load: ' . $key; - } - } - - /** - * Returns true if an error occurred. - * @access public - * @return bool - */ - public function IsError() { - return ($this->error_count > 0); - } - - /** - * Changes every end of line from CRLF, CR or LF to $this->LE. - * @access public - * @param string $str String to FixEOL - * @return string - */ - public function FixEOL($str) { - // condense down to \n - $nstr = str_replace(array("\r\n", "\r"), "\n", $str); - // Now convert LE as needed - if ($this->LE !== "\n") { - $nstr = str_replace("\n", $this->LE, $nstr); - } - return $nstr; - } - - /** - * Adds a custom header. $name value can be overloaded to contain - * both header name and value (name:value) - * @access public - * @param string $name custom header name - * @param string $value header value - * @return void - */ - public function AddCustomHeader($name, $value=null) { - if ($value === null) { - // Value passed in as name:value - $this->CustomHeader[] = explode(':', $name, 2); - } else { - $this->CustomHeader[] = array($name, $value); - } - } - - /** - * Evaluates the message and returns modifications for inline images and backgrounds - * Overwrites any existing values in $this->Body and $this->AltBody - * @access public - * @param string $message Text to be HTML modified - * @param string $basedir baseline directory for path - * @return string $message - */ - public function MsgHTML($message, $basedir = '') { - preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images); - if(isset($images[2])) { - foreach($images[2] as $i => $url) { - // do not change urls for absolute images (thanks to corvuscorax) - if (!preg_match('#^[A-z]+://#', $url)) { - $filename = basename($url); - $directory = dirname($url); - if ($directory == '.') { - $directory = ''; - } - $cid = 'cid:' . md5($url); - $ext = pathinfo($filename, PATHINFO_EXTENSION); - $mimeType = self::_mime_types($ext); - if ( strlen($basedir) > 1 && substr($basedir, -1) != '/') { $basedir .= '/'; } - if ( strlen($directory) > 1 && substr($directory, -1) != '/') { $directory .= '/'; } - if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($url), $filename, 'base64', $mimeType) ) { - $message = preg_replace("/".$images[1][$i]."=[\"']".preg_quote($url, '/')."[\"']/Ui", $images[1][$i]."=\"".$cid."\"", $message); - } - } - } - } - $this->IsHTML(true); - $this->Body = $message; - $this->AltBody = $this->html2text($message); - if (empty($this->AltBody)) { - $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n"; - } - return $message; - } - - /** - * Convert an HTML string into a plain text version - * @param string $html The HTML text to convert - * @return string - */ - public function html2text($html) { - return html_entity_decode(trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $html))), ENT_QUOTES, $this->CharSet); - } - - /** - * Gets the MIME type of the embedded or inline image - * @param string $ext File extension - * @access public - * @return string MIME type of ext - * @static - */ - public static function _mime_types($ext = '') { - $mimes = array( - 'xl' => 'application/excel', - 'hqx' => 'application/mac-binhex40', - 'cpt' => 'application/mac-compactpro', - 'bin' => 'application/macbinary', - 'doc' => 'application/msword', - 'word' => 'application/msword', - 'class' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'dms' => 'application/octet-stream', - 'exe' => 'application/octet-stream', - 'lha' => 'application/octet-stream', - 'lzh' => 'application/octet-stream', - 'psd' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'so' => 'application/octet-stream', - 'oda' => 'application/oda', - 'pdf' => 'application/pdf', - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'mif' => 'application/vnd.mif', - 'xls' => 'application/vnd.ms-excel', - 'ppt' => 'application/vnd.ms-powerpoint', - 'wbxml' => 'application/vnd.wap.wbxml', - 'wmlc' => 'application/vnd.wap.wmlc', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dxr' => 'application/x-director', - 'dvi' => 'application/x-dvi', - 'gtar' => 'application/x-gtar', - 'php3' => 'application/x-httpd-php', - 'php4' => 'application/x-httpd-php', - 'php' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'js' => 'application/x-javascript', - 'swf' => 'application/x-shockwave-flash', - 'sit' => 'application/x-stuffit', - 'tar' => 'application/x-tar', - 'tgz' => 'application/x-tar', - 'xht' => 'application/xhtml+xml', - 'xhtml' => 'application/xhtml+xml', - 'zip' => 'application/zip', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mp2' => 'audio/mpeg', - 'mp3' => 'audio/mpeg', - 'mpga' => 'audio/mpeg', - 'aif' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'ram' => 'audio/x-pn-realaudio', - 'rm' => 'audio/x-pn-realaudio', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'ra' => 'audio/x-realaudio', - 'wav' => 'audio/x-wav', - 'bmp' => 'image/bmp', - 'gif' => 'image/gif', - 'jpeg' => 'image/jpeg', - 'jpe' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'png' => 'image/png', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'eml' => 'message/rfc822', - 'css' => 'text/css', - 'html' => 'text/html', - 'htm' => 'text/html', - 'shtml' => 'text/html', - 'log' => 'text/plain', - 'text' => 'text/plain', - 'txt' => 'text/plain', - 'rtx' => 'text/richtext', - 'rtf' => 'text/rtf', - 'xml' => 'text/xml', - 'xsl' => 'text/xml', - 'mpeg' => 'video/mpeg', - 'mpe' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mov' => 'video/quicktime', - 'qt' => 'video/quicktime', - 'rv' => 'video/vnd.rn-realvideo', - 'avi' => 'video/x-msvideo', - 'movie' => 'video/x-sgi-movie' - ); - return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; - } - - /** - * Set (or reset) Class Objects (variables) - * - * Usage Example: - * $page->set('X-Priority', '3'); - * - * @access public - * @param string $name Parameter Name - * @param mixed $value Parameter Value - * NOTE: will not work with arrays, there are no arrays to set/reset - * @throws phpmailerException - * @return bool - * @todo Should this not be using __set() magic function? - */ - public function set($name, $value = '') { - try { - if (isset($this->$name) ) { - $this->$name = $value; - } else { - throw new phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL); - } - } catch (Exception $e) { - $this->SetError($e->getMessage()); - if ($e->getCode() == self::STOP_CRITICAL) { - return false; - } - } - return true; - } - - /** - * Strips newlines to prevent header injection. - * @access public - * @param string $str String - * @return string - */ - public function SecureHeader($str) { - return trim(str_replace(array("\r", "\n"), '', $str)); - } - - /** - * Set the private key file and password to sign the message. - * - * @access public - * @param $cert_filename - * @param string $key_filename Parameter File Name - * @param string $key_pass Password for private key - */ - public function Sign($cert_filename, $key_filename, $key_pass) { - $this->sign_cert_file = $cert_filename; - $this->sign_key_file = $key_filename; - $this->sign_key_pass = $key_pass; - } - - /** - * Set the private key file and password to sign the message. - * - * @access public - * @param string $txt - * @return string - */ - public function DKIM_QP($txt) { - $line = ''; - for ($i = 0; $i < strlen($txt); $i++) { - $ord = ord($txt[$i]); - if ( ((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E)) ) { - $line .= $txt[$i]; - } else { - $line .= "=".sprintf("%02X", $ord); - } - } - return $line; - } - - /** - * Generate DKIM signature - * - * @access public - * @param string $s Header - * @throws phpmailerException - * @return string - */ - public function DKIM_Sign($s) { - if (!defined('PKCS7_TEXT')) { - if ($this->exceptions) { - throw new phpmailerException($this->Lang("signing").' OpenSSL extension missing.'); - } - return ''; - } - $privKeyStr = file_get_contents($this->DKIM_private); - if ($this->DKIM_passphrase != '') { - $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase); - } else { - $privKey = $privKeyStr; - } - if (openssl_sign($s, $signature, $privKey)) { - return base64_encode($signature); - } - return ''; - } - - /** - * Generate DKIM Canonicalization Header - * - * @access public - * @param string $s Header - * @return string - */ - public function DKIM_HeaderC($s) { - $s = preg_replace("/\r\n\s+/", " ", $s); - $lines = explode("\r\n", $s); - foreach ($lines as $key => $line) { - list($heading, $value) = explode(":", $line, 2); - $heading = strtolower($heading); - $value = preg_replace("/\s+/", " ", $value) ; // Compress useless spaces - $lines[$key] = $heading.":".trim($value) ; // Don't forget to remove WSP around the value - } - $s = implode("\r\n", $lines); - return $s; - } - - /** - * Generate DKIM Canonicalization Body - * - * @access public - * @param string $body Message Body - * @return string - */ - public function DKIM_BodyC($body) { - if ($body == '') return "\r\n"; - // stabilize line endings - $body = str_replace("\r\n", "\n", $body); - $body = str_replace("\n", "\r\n", $body); - // END stabilize line endings - while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") { - $body = substr($body, 0, strlen($body) - 2); - } - return $body; - } - - /** - * Create the DKIM header, body, as new header - * - * @access public - * @param string $headers_line Header lines - * @param string $subject Subject - * @param string $body Body - * @return string - */ - public function DKIM_Add($headers_line, $subject, $body) { - $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms - $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body - $DKIMquery = 'dns/txt'; // Query method - $DKIMtime = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) - $subject_header = "Subject: $subject"; - $headers = explode($this->LE, $headers_line); - $from_header = ""; - $to_header = ""; - foreach($headers as $header) { - if (strpos($header, 'From:') === 0) { - $from_header = $header; - } elseif (strpos($header, 'To:') === 0) { - $to_header = $header; - } - } - $from = str_replace('|', '=7C', $this->DKIM_QP($from_header)); - $to = str_replace('|', '=7C', $this->DKIM_QP($to_header)); - $subject = str_replace('|', '=7C', $this->DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable - $body = $this->DKIM_BodyC($body); - $DKIMlen = strlen($body) ; // Length of body - $DKIMb64 = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body - $ident = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";"; - $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n". - "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n". - "\th=From:To:Subject;\r\n". - "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n". - "\tz=$from\r\n". - "\t|$to\r\n". - "\t|$subject;\r\n". - "\tbh=" . $DKIMb64 . ";\r\n". - "\tb="; - $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs); - $signed = $this->DKIM_Sign($toSign); - return "X-PHPMAILER-DKIM: code.google.com/a/apache-extras.org/p/phpmailer/\r\n".$dkimhdrs.$signed."\r\n"; - } - - /** - * Perform callback - * @param boolean $isSent - * @param string $to - * @param string $cc - * @param string $bcc - * @param string $subject - * @param string $body - * @param string $from - */ - protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from = null) { - if (!empty($this->action_function) && is_callable($this->action_function)) { - $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from); - call_user_func_array($this->action_function, $params); - } - } -} - -/** - * Exception handler for PHPMailer - * @package PHPMailer - */ -class phpmailerException extends Exception { - /** - * Prettify error message output - * @return string - */ - public function errorMessage() { - $errorMsg = '' . $this->getMessage() . "';
-
- foreach ($this->error as $single_error) {
- print_r($single_error);
- }
-
- echo '';
- }
-
- /**
- * Takes over from PHP for the socket warning handler
- * @access private
- * @param integer $errno
- * @param string $errstr
- * @param string $errfile
- * @param integer $errline
- */
- private function catchWarning ($errno, $errstr, $errfile, $errline) {
- $this->error[] = array(
- 'error' => "Connecting to the POP3 server raised a PHP warning: ",
- 'errno' => $errno,
- 'errstr' => $errstr
- );
- }
-
- // End of class
-}
diff --git a/download/phpmailer/class.smtp.php b/download/phpmailer/class.smtp.php
deleted file mode 100755
index f0e4062ec..000000000
--- a/download/phpmailer/class.smtp.php
+++ /dev/null
@@ -1,1087 +0,0 @@
-Debugoutput == 'error_log') {
- error_log($str);
- } else {
- echo $str;
- }
- }
-
- /**
- * Initialize the class so that the data is in a known state.
- * @access public
- * @return SMTP
- */
- public function __construct() {
- $this->smtp_conn = 0;
- $this->error = null;
- $this->helo_rply = null;
-
- $this->do_debug = 0;
- }
-
- /////////////////////////////////////////////////
- // CONNECTION FUNCTIONS
- /////////////////////////////////////////////////
-
- /**
- * Connect to the server specified on the port specified.
- * If the port is not specified use the default SMTP_PORT.
- * If tval is specified then a connection will try and be
- * established with the server for that number of seconds.
- * If tval is not specified the default is 30 seconds to
- * try on the connection.
- *
- * SMTP CODE SUCCESS: 220
- * SMTP CODE FAILURE: 421
- * @access public
- * @param string $host
- * @param int $port
- * @param int $tval
- * @return bool
- */
- public function Connect($host, $port = 0, $tval = 30) {
- // set the error val to null so there is no confusion
- $this->error = null;
-
- // make sure we are __not__ connected
- if($this->connected()) {
- // already connected, generate error
- $this->error = array('error' => 'Already connected to a server');
- return false;
- }
-
- if(empty($port)) {
- $port = $this->SMTP_PORT;
- }
-
- // connect to the smtp server
- $this->smtp_conn = @fsockopen($host, // the host of the server
- $port, // the port to use
- $errno, // error number if any
- $errstr, // error message if any
- $tval); // give up after ? secs
- // verify we connected properly
- if(empty($this->smtp_conn)) {
- $this->error = array('error' => 'Failed to connect to server',
- 'errno' => $errno,
- 'errstr' => $errstr);
- if($this->do_debug >= 1) {
- $this->edebug('SMTP -> ERROR: ' . $this->error['error'] . ": $errstr ($errno)" . $this->CRLF . '
- * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
- *
- * @type string|callable
- * @see SMTP::$Debugoutput
- */
- public $Debugoutput = 'echo';
-
- /**
- * Whether to keep SMTP connection open after each message.
- * If this is set to true then to close the connection
- * requires an explicit call to smtpClose().
- * @type boolean
- */
- public $SMTPKeepAlive = false;
-
- /**
- * Whether to split multiple to addresses into multiple messages
- * or send them all in one message.
- * @type boolean
- */
- public $SingleTo = false;
-
- /**
- * Storage for addresses when SingleTo is enabled.
- * @type array
- * @TODO This should really not be public
- */
- public $SingleToArray = array();
-
- /**
- * Whether to generate VERP addresses on send.
- * Only applicable when sending via SMTP.
- * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
- * @link http://www.postfix.org/VERP_README.html Postfix VERP info
- * @type boolean
- */
- public $do_verp = false;
-
- /**
- * Whether to allow sending messages with an empty body.
- * @type boolean
- */
- public $AllowEmpty = false;
-
- /**
- * The default line ending.
- * @note The default remains "\n". We force CRLF where we know
- * it must be used via self::CRLF.
- * @type string
- */
- public $LE = "\n";
-
- /**
- * DKIM selector.
- * @type string
- */
- public $DKIM_selector = '';
-
- /**
- * DKIM Identity.
- * Usually the email address used as the source of the email
- * @type string
- */
- public $DKIM_identity = '';
-
- /**
- * DKIM passphrase.
- * Used if your key is encrypted.
- * @type string
- */
- public $DKIM_passphrase = '';
-
- /**
- * DKIM signing domain name.
- * @example 'example.com'
- * @type string
- */
- public $DKIM_domain = '';
-
- /**
- * DKIM private key file path.
- * @type string
- */
- public $DKIM_private = '';
-
- /**
- * Callback Action function name.
- *
- * The function that handles the result of the send email action.
- * It is called out by send() for each email sent.
- *
- * Value can be any php callable: http://www.php.net/is_callable
- *
- * Parameters:
- * boolean $result result of the send action
- * string $to email address of the recipient
- * string $cc cc email addresses
- * string $bcc bcc email addresses
- * string $subject the subject
- * string $body the email body
- * string $from email address of sender
- * @type string
- */
- public $action_function = '';
-
- /**
- * What to use in the X-Mailer header.
- * Options: null for default, whitespace for none, or a string to use
- * @type string
- */
- public $XMailer = '';
-
- /**
- * An instance of the SMTP sender class.
- * @type SMTP
- * @access protected
- */
- protected $smtp = null;
-
- /**
- * The array of 'to' addresses.
- * @type array
- * @access protected
- */
- protected $to = array();
-
- /**
- * The array of 'cc' addresses.
- * @type array
- * @access protected
- */
- protected $cc = array();
-
- /**
- * The array of 'bcc' addresses.
- * @type array
- * @access protected
- */
- protected $bcc = array();
-
- /**
- * The array of reply-to names and addresses.
- * @type array
- * @access protected
- */
- protected $ReplyTo = array();
-
- /**
- * An array of all kinds of addresses.
- * Includes all of $to, $cc, $bcc, $replyto
- * @type array
- * @access protected
- */
- protected $all_recipients = array();
-
- /**
- * The array of attachments.
- * @type array
- * @access protected
- */
- protected $attachment = array();
-
- /**
- * The array of custom headers.
- * @type array
- * @access protected
- */
- protected $CustomHeader = array();
-
- /**
- * The most recent Message-ID (including angular brackets).
- * @type string
- * @access protected
- */
- protected $lastMessageID = '';
-
- /**
- * The message's MIME type.
- * @type string
- * @access protected
- */
- protected $message_type = '';
-
- /**
- * The array of MIME boundary strings.
- * @type array
- * @access protected
- */
- protected $boundary = array();
-
- /**
- * The array of available languages.
- * @type array
- * @access protected
- */
- protected $language = array();
-
- /**
- * The number of errors encountered.
- * @type integer
- * @access protected
- */
- protected $error_count = 0;
-
- /**
- * The S/MIME certificate file path.
- * @type string
- * @access protected
- */
- protected $sign_cert_file = '';
-
- /**
- * The S/MIME key file path.
- * @type string
- * @access protected
- */
- protected $sign_key_file = '';
-
- /**
- * The S/MIME password for the key.
- * Used only if the key is encrypted.
- * @type string
- * @access protected
- */
- protected $sign_key_pass = '';
-
- /**
- * Whether to throw exceptions for errors.
- * @type boolean
- * @access protected
- */
- protected $exceptions = false;
-
- /**
- * Error severity: message only, continue processing.
- */
- const STOP_MESSAGE = 0;
-
- /**
- * Error severity: message, likely ok to continue processing.
- */
- const STOP_CONTINUE = 1;
-
- /**
- * Error severity: message, plus full stop, critical error reached.
- */
- const STOP_CRITICAL = 2;
-
- /**
- * SMTP RFC standard line ending.
- */
- const CRLF = "\r\n";
-
- /**
- * Constructor.
- * @param boolean $exceptions Should we throw external exceptions?
- */
- public function __construct($exceptions = false)
- {
- $this->exceptions = (boolean)$exceptions;
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- if ($this->Mailer == 'smtp') { //close any open SMTP connection nicely
- $this->smtpClose();
- }
- }
-
- /**
- * Call mail() in a safe_mode-aware fashion.
- * Also, unless sendmail_path points to sendmail (or something that
- * claims to be sendmail), don't pass params (not a perfect fix,
- * but it will do)
- * @param string $to To
- * @param string $subject Subject
- * @param string $body Message Body
- * @param string $header Additional Header(s)
- * @param string $params Params
- * @access private
- * @return boolean
- */
- private function mailPassthru($to, $subject, $body, $header, $params)
- {
- //Check overloading of mail function to avoid double-encoding
- if (ini_get('mbstring.func_overload') & 1) {
- $subject = $this->secureHeader($subject);
- } else {
- $subject = $this->encodeHeader($this->secureHeader($subject));
- }
- if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
- $result = @mail($to, $subject, $body, $header);
- } else {
- $result = @mail($to, $subject, $body, $header, $params);
- }
- return $result;
- }
-
- /**
- * Output debugging info via user-defined method.
- * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug).
- * @see PHPMailer::$Debugoutput
- * @see PHPMailer::$SMTPDebug
- * @param string $str
- */
- protected function edebug($str)
- {
- if ($this->SMTPDebug <= 0) {
- return;
- }
- //Avoid clash with built-in function names
- if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
- call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
- return;
- }
- switch ($this->Debugoutput) {
- case 'error_log':
- //Don't output, just log
- error_log($str);
- break;
- case 'html':
- //Cleans up output a bit for a better looking, HTML-safe output
- echo htmlentities(
- preg_replace('/[\r\n]+/', '', $str),
- ENT_QUOTES,
- 'UTF-8'
- )
- . "' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "
\n"; - } - } - $this->ErrorInfo = $msg; - } - - /** - * Return an RFC 822 formatted date. - * @access public - * @return string - * @static - */ - public static function rfcDate() - { - // Set the time zone to whatever the default is to avoid 500 errors - // Will default to UTC if it's not set properly in php.ini - date_default_timezone_set(@date_default_timezone_get()); - return date('D, j M Y H:i:s O'); - } - - /** - * Get the server hostname. - * Returns 'localhost.localdomain' if unknown. - * @access protected - * @return string - */ - protected function serverHostname() - { - $result = 'localhost.localdomain'; - if (!empty($this->Hostname)) { - $result = $this->Hostname; - } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { - $result = $_SERVER['SERVER_NAME']; - } elseif (function_exists('gethostname') && gethostname() !== false) { - $result = gethostname(); - } elseif (php_uname('n') !== false) { - $result = php_uname('n'); - } - return $result; - } - - /** - * Get an error message in the current language. - * @access protected - * @param string $key - * @return string - */ - protected function lang($key) - { - if (count($this->language) < 1) { - $this->setLanguage('en'); // set the default language - } - - if (isset($this->language[$key])) { - return $this->language[$key]; - } else { - return 'Language string failed to load: ' . $key; - } - } - - /** - * Check if an error occurred. - * @access public - * @return boolean True if an error did occur. - */ - public function isError() - { - return ($this->error_count > 0); - } - - /** - * Ensure consistent line endings in a string. - * Changes every end of line from CRLF, CR or LF to $this->LE. - * @access public - * @param string $str String to fixEOL - * @return string - */ - public function fixEOL($str) - { - // Normalise to \n - $nstr = str_replace(array("\r\n", "\r"), "\n", $str); - // Now convert LE as needed - if ($this->LE !== "\n") { - $nstr = str_replace("\n", $this->LE, $nstr); - } - return $nstr; - } - - /** - * Add a custom header. - * $name value can be overloaded to contain - * both header name and value (name:value) - * @access public - * @param string $name Custom header name - * @param string $value Header value - * @return void - */ - public function addCustomHeader($name, $value = null) - { - if ($value === null) { - // Value passed in as name:value - $this->CustomHeader[] = explode(':', $name, 2); - } else { - $this->CustomHeader[] = array($name, $value); - } - } - - /** - * Create a message from an HTML string. - * Automatically makes modifications for inline images and backgrounds - * and creates a plain-text version by converting the HTML. - * Overwrites any existing values in $this->Body and $this->AltBody - * @access public - * @param string $message HTML message string - * @param string $basedir baseline directory for path - * @param boolean|callable $advanced Whether to use the internal HTML to text converter - * or your own custom converter @see html2text() - * @return string $message - */ - public function msgHTML($message, $basedir = '', $advanced = false) - { - preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images); - if (isset($images[2])) { - foreach ($images[2] as $imgindex => $url) { - // Convert data URIs into embedded images - if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) { - $data = substr($url, strpos($url, ',')); - if ($match[2]) { - $data = base64_decode($data); - } else { - $data = rawurldecode($data); - } - $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2 - if ($this->addStringEmbeddedImage($data, $cid, '', 'base64', $match[1])) { - $message = str_replace( - $images[0][$imgindex], - $images[1][$imgindex] . '="cid:' . $cid . '"', - $message - ); - } - } elseif (!preg_match('#^[A-z]+://#', $url)) { - // Do not change urls for absolute images (thanks to corvuscorax) - $filename = basename($url); - $directory = dirname($url); - if ($directory == '.') { - $directory = ''; - } - $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2 - if (strlen($basedir) > 1 && substr($basedir, -1) != '/') { - $basedir .= '/'; - } - if (strlen($directory) > 1 && substr($directory, -1) != '/') { - $directory .= '/'; - } - if ($this->addEmbeddedImage( - $basedir . $directory . $filename, - $cid, - $filename, - 'base64', - self::_mime_types((string)self::mb_pathinfo($filename, PATHINFO_EXTENSION)) - ) - ) { - $message = preg_replace( - '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui', - $images[1][$imgindex] . '="cid:' . $cid . '"', - $message - ); - } - } - } - } - $this->isHTML(true); - // Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better - $this->Body = $this->normalizeBreaks($message); - $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced)); - if (empty($this->AltBody)) { - $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . - self::CRLF . self::CRLF; - } - return $this->Body; - } - - /** - * Convert an HTML string into plain text. - * This is used by msgHTML(). - * Note - older versions of this function used a bundled advanced converter - * which was been removed for license reasons in #232 - * Example usage: - *
- * // Use default conversion
- * $plain = $mail->html2text($html);
- * // Use your own custom converter
- * $plain = $mail->html2text($html, function($html) {
- * $converter = new MyHtml2text($html);
- * return $converter->get_text();
- * });
- *
- * @param string $html The HTML text to convert
- * @param boolean|callable $advanced Any boolean value to use the internal converter,
- * or provide your own callable for custom conversion.
- * @return string
- */
- public function html2text($html, $advanced = false)
- {
- if (is_callable($advanced)) {
- return call_user_func($advanced, $html);
- }
- return html_entity_decode(
- trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))),
- ENT_QUOTES,
- $this->CharSet
- );
- }
-
- /**
- * Get the MIME type for a file extension.
- * @param string $ext File extension
- * @access public
- * @return string MIME type of file.
- * @static
- */
- public static function _mime_types($ext = '')
- {
- $mimes = array(
- 'xl' => 'application/excel',
- 'js' => 'application/javascript',
- 'hqx' => 'application/mac-binhex40',
- 'cpt' => 'application/mac-compactpro',
- 'bin' => 'application/macbinary',
- 'doc' => 'application/msword',
- 'word' => 'application/msword',
- 'class' => 'application/octet-stream',
- 'dll' => 'application/octet-stream',
- 'dms' => 'application/octet-stream',
- 'exe' => 'application/octet-stream',
- 'lha' => 'application/octet-stream',
- 'lzh' => 'application/octet-stream',
- 'psd' => 'application/octet-stream',
- 'sea' => 'application/octet-stream',
- 'so' => 'application/octet-stream',
- 'oda' => 'application/oda',
- 'pdf' => 'application/pdf',
- 'ai' => 'application/postscript',
- 'eps' => 'application/postscript',
- 'ps' => 'application/postscript',
- 'smi' => 'application/smil',
- 'smil' => 'application/smil',
- 'mif' => 'application/vnd.mif',
- 'xls' => 'application/vnd.ms-excel',
- 'ppt' => 'application/vnd.ms-powerpoint',
- 'wbxml' => 'application/vnd.wap.wbxml',
- 'wmlc' => 'application/vnd.wap.wmlc',
- 'dcr' => 'application/x-director',
- 'dir' => 'application/x-director',
- 'dxr' => 'application/x-director',
- 'dvi' => 'application/x-dvi',
- 'gtar' => 'application/x-gtar',
- 'php3' => 'application/x-httpd-php',
- 'php4' => 'application/x-httpd-php',
- 'php' => 'application/x-httpd-php',
- 'phtml' => 'application/x-httpd-php',
- 'phps' => 'application/x-httpd-php-source',
- 'swf' => 'application/x-shockwave-flash',
- 'sit' => 'application/x-stuffit',
- 'tar' => 'application/x-tar',
- 'tgz' => 'application/x-tar',
- 'xht' => 'application/xhtml+xml',
- 'xhtml' => 'application/xhtml+xml',
- 'zip' => 'application/zip',
- 'mid' => 'audio/midi',
- 'midi' => 'audio/midi',
- 'mp2' => 'audio/mpeg',
- 'mp3' => 'audio/mpeg',
- 'mpga' => 'audio/mpeg',
- 'aif' => 'audio/x-aiff',
- 'aifc' => 'audio/x-aiff',
- 'aiff' => 'audio/x-aiff',
- 'ram' => 'audio/x-pn-realaudio',
- 'rm' => 'audio/x-pn-realaudio',
- 'rpm' => 'audio/x-pn-realaudio-plugin',
- 'ra' => 'audio/x-realaudio',
- 'wav' => 'audio/x-wav',
- 'bmp' => 'image/bmp',
- 'gif' => 'image/gif',
- 'jpeg' => 'image/jpeg',
- 'jpe' => 'image/jpeg',
- 'jpg' => 'image/jpeg',
- 'png' => 'image/png',
- 'tiff' => 'image/tiff',
- 'tif' => 'image/tiff',
- 'eml' => 'message/rfc822',
- 'css' => 'text/css',
- 'html' => 'text/html',
- 'htm' => 'text/html',
- 'shtml' => 'text/html',
- 'log' => 'text/plain',
- 'text' => 'text/plain',
- 'txt' => 'text/plain',
- 'rtx' => 'text/richtext',
- 'rtf' => 'text/rtf',
- 'vcf' => 'text/vcard',
- 'vcard' => 'text/vcard',
- 'xml' => 'text/xml',
- 'xsl' => 'text/xml',
- 'mpeg' => 'video/mpeg',
- 'mpe' => 'video/mpeg',
- 'mpg' => 'video/mpeg',
- 'mov' => 'video/quicktime',
- 'qt' => 'video/quicktime',
- 'rv' => 'video/vnd.rn-realvideo',
- 'avi' => 'video/x-msvideo',
- 'movie' => 'video/x-sgi-movie'
- );
- return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]: 'application/octet-stream');
- }
-
- /**
- * Map a file name to a MIME type.
- * Defaults to 'application/octet-stream', i.e.. arbitrary binary data.
- * @param string $filename A file name or full path, does not need to exist as a file
- * @return string
- * @static
- */
- public static function filenameToType($filename)
- {
- // In case the path is a URL, strip any query string before getting extension
- $qpos = strpos($filename, '?');
- if (false !== $qpos) {
- $filename = substr($filename, 0, $qpos);
- }
- $pathinfo = self::mb_pathinfo($filename);
- return self::_mime_types($pathinfo['extension']);
- }
-
- /**
- * Multi-byte-safe pathinfo replacement.
- * Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe.
- * Works similarly to the one in PHP >= 5.2.0
- * @link http://www.php.net/manual/en/function.pathinfo.php#107461
- * @param string $path A filename or path, does not need to exist as a file
- * @param integer|string $options Either a PATHINFO_* constant,
- * or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2
- * @return string|array
- * @static
- */
- public static function mb_pathinfo($path, $options = null)
- {
- $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
- $pathinfo = array();
- if (preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo)) {
- if (array_key_exists(1, $pathinfo)) {
- $ret['dirname'] = $pathinfo[1];
- }
- if (array_key_exists(2, $pathinfo)) {
- $ret['basename'] = $pathinfo[2];
- }
- if (array_key_exists(5, $pathinfo)) {
- $ret['extension'] = $pathinfo[5];
- }
- if (array_key_exists(3, $pathinfo)) {
- $ret['filename'] = $pathinfo[3];
- }
- }
- switch ($options) {
- case PATHINFO_DIRNAME:
- case 'dirname':
- return $ret['dirname'];
- case PATHINFO_BASENAME:
- case 'basename':
- return $ret['basename'];
- case PATHINFO_EXTENSION:
- case 'extension':
- return $ret['extension'];
- case PATHINFO_FILENAME:
- case 'filename':
- return $ret['filename'];
- default:
- return $ret;
- }
- }
-
- /**
- * Set or reset instance properties.
- *
- * Usage Example:
- * $page->set('X-Priority', '3');
- *
- * @access public
- * @param string $name
- * @param mixed $value
- * NOTE: will not work with arrays, there are no arrays to set/reset
- * @throws phpmailerException
- * @return boolean
- * @TODO Should this not be using __set() magic function?
- */
- public function set($name, $value = '')
- {
- try {
- if (isset($this->$name)) {
- $this->$name = $value;
- } else {
- throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL);
- }
- } catch (Exception $exc) {
- $this->setError($exc->getMessage());
- if ($exc->getCode() == self::STOP_CRITICAL) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Strip newlines to prevent header injection.
- * @access public
- * @param string $str
- * @return string
- */
- public function secureHeader($str)
- {
- return trim(str_replace(array("\r", "\n"), '', $str));
- }
-
- /**
- * Normalize line breaks in a string.
- * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format.
- * Defaults to CRLF (for message bodies) and preserves consecutive breaks.
- * @param string $text
- * @param string $breaktype What kind of line break to use, defaults to CRLF
- * @return string
- * @access public
- * @static
- */
- public static function normalizeBreaks($text, $breaktype = "\r\n")
- {
- return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text);
- }
-
-
- /**
- * Set the public and private key files and password for S/MIME signing.
- * @access public
- * @param string $cert_filename
- * @param string $key_filename
- * @param string $key_pass Password for private key
- */
- public function sign($cert_filename, $key_filename, $key_pass)
- {
- $this->sign_cert_file = $cert_filename;
- $this->sign_key_file = $key_filename;
- $this->sign_key_pass = $key_pass;
- }
-
- /**
- * Quoted-Printable-encode a DKIM header.
- * @access public
- * @param string $txt
- * @return string
- */
- public function DKIM_QP($txt)
- {
- $line = '';
- for ($i = 0; $i < strlen($txt); $i++) {
- $ord = ord($txt[$i]);
- if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
- $line .= $txt[$i];
- } else {
- $line .= '=' . sprintf('%02X', $ord);
- }
- }
- return $line;
- }
-
- /**
- * Generate a DKIM signature.
- * @access public
- * @param string $signHeader
- * @throws phpmailerException
- * @return string
- */
- public function DKIM_Sign($signHeader)
- {
- if (!defined('PKCS7_TEXT')) {
- if ($this->exceptions) {
- throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
- }
- return '';
- }
- $privKeyStr = file_get_contents($this->DKIM_private);
- if ($this->DKIM_passphrase != '') {
- $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
- } else {
- $privKey = $privKeyStr;
- }
- if (openssl_sign($signHeader, $signature, $privKey)) {
- return base64_encode($signature);
- }
- return '';
- }
-
- /**
- * Generate a DKIM canonicalization header.
- * @access public
- * @param string $signHeader Header
- * @return string
- */
- public function DKIM_HeaderC($signHeader)
- {
- $signHeader = preg_replace('/\r\n\s+/', ' ', $signHeader);
- $lines = explode("\r\n", $signHeader);
- foreach ($lines as $key => $line) {
- list($heading, $value) = explode(':', $line, 2);
- $heading = strtolower($heading);
- $value = preg_replace('/\s+/', ' ', $value); // Compress useless spaces
- $lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value
- }
- $signHeader = implode("\r\n", $lines);
- return $signHeader;
- }
-
- /**
- * Generate a DKIM canonicalization body.
- * @access public
- * @param string $body Message Body
- * @return string
- */
- public function DKIM_BodyC($body)
- {
- if ($body == '') {
- return "\r\n";
- }
- // stabilize line endings
- $body = str_replace("\r\n", "\n", $body);
- $body = str_replace("\n", "\r\n", $body);
- // END stabilize line endings
- while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
- $body = substr($body, 0, strlen($body) - 2);
- }
- return $body;
- }
-
- /**
- * Create the DKIM header and body in a new message header.
- * @access public
- * @param string $headers_line Header lines
- * @param string $subject Subject
- * @param string $body Body
- * @return string
- */
- public function DKIM_Add($headers_line, $subject, $body)
- {
- $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
- $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
- $DKIMquery = 'dns/txt'; // Query method
- $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
- $subject_header = "Subject: $subject";
- $headers = explode($this->LE, $headers_line);
- $from_header = '';
- $to_header = '';
- $current = '';
- foreach ($headers as $header) {
- if (strpos($header, 'From:') === 0) {
- $from_header = $header;
- $current = 'from_header';
- } elseif (strpos($header, 'To:') === 0) {
- $to_header = $header;
- $current = 'to_header';
- } else {
- if ($current && strpos($header, ' =?') === 0) {
- $current .= $header;
- } else {
- $current = '';
- }
- }
- }
- $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
- $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
- $subject = str_replace(
- '|',
- '=7C',
- $this->DKIM_QP($subject_header)
- ); // Copied header fields (dkim-quoted-printable)
- $body = $this->DKIM_BodyC($body);
- $DKIMlen = strlen($body); // Length of body
- $DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1 hash of body
- $ident = ($this->DKIM_identity == '') ? '' : ' i=' . $this->DKIM_identity . ';';
- $dkimhdrs = 'DKIM-Signature: v=1; a=' .
- $DKIMsignatureType . '; q=' .
- $DKIMquery . '; l=' .
- $DKIMlen . '; s=' .
- $this->DKIM_selector .
- ";\r\n" .
- "\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" .
- "\th=From:To:Subject;\r\n" .
- "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" .
- "\tz=$from\r\n" .
- "\t|$to\r\n" .
- "\t|$subject;\r\n" .
- "\tbh=" . $DKIMb64 . ";\r\n" .
- "\tb=";
- $toSign = $this->DKIM_HeaderC(
- $from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs
- );
- $signed = $this->DKIM_Sign($toSign);
- return $dkimhdrs . $signed . "\r\n";
- }
-
- /**
- * Allows for public read access to 'to' property.
- * @access public
- * @return array
- */
- public function getToAddresses()
- {
- return $this->to;
- }
-
- /**
- * Allows for public read access to 'cc' property.
- * @access public
- * @return array
- */
- public function getCcAddresses()
- {
- return $this->cc;
- }
-
- /**
- * Allows for public read access to 'bcc' property.
- * @access public
- * @return array
- */
- public function getBccAddresses()
- {
- return $this->bcc;
- }
-
- /**
- * Allows for public read access to 'ReplyTo' property.
- * @access public
- * @return array
- */
- public function getReplyToAddresses()
- {
- return $this->ReplyTo;
- }
-
- /**
- * Allows for public read access to 'all_recipients' property.
- * @access public
- * @return array
- */
- public function getAllRecipientAddresses()
- {
- return $this->all_recipients;
- }
-
- /**
- * Perform a callback.
- * @param boolean $isSent
- * @param array $to
- * @param array $cc
- * @param array $bcc
- * @param string $subject
- * @param string $body
- * @param string $from
- */
- protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from)
- {
- if (!empty($this->action_function) && is_callable($this->action_function)) {
- $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
- call_user_func_array($this->action_function, $params);
- }
- }
-}
-
-/**
- * PHPMailer exception handler
- * @package PHPMailer
- */
-class phpmailerException extends Exception
-{
- /**
- * Prettify error message output
- * @return string
- */
- public function errorMessage()
- {
- $errorMsg = '' . $this->getMessage() . "';
- foreach ($this->errors as $error) {
- print_r($error);
- }
- echo '';
- }
- }
-
- /**
- * POP3 connection error handler.
- * @param integer $errno
- * @param string $errstr
- * @param string $errfile
- * @param integer $errline
- * @access private
- */
- private function catchWarning($errno, $errstr, $errfile, $errline)
- {
- $this->setError(array(
- 'error' => "Connecting to the POP3 server raised a PHP warning: ",
- 'errno' => $errno,
- 'errstr' => $errstr,
- 'errfile' => $errfile,
- 'errline' => $errline
- ));
- }
-}
diff --git a/download/phpmailer529/class.smtp.php b/download/phpmailer529/class.smtp.php
deleted file mode 100755
index d6991970f..000000000
--- a/download/phpmailer529/class.smtp.php
+++ /dev/null
@@ -1,1132 +0,0 @@
-
- * @author Jim Jagielski (jimjag)
- * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
- *
- * @type string|callable
- */
- public $Debugoutput = 'echo';
-
- /**
- * Whether to use VERP.
- * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
- * @link http://www.postfix.org/VERP_README.html Info on VERP
- * @type boolean
- */
- public $do_verp = false;
-
- /**
- * The timeout value for connection, in seconds.
- * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
- * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
- * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2
- * @type integer
- */
- public $Timeout = 300;
-
- /**
- * How long to wait for commands to complete, in seconds.
- * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
- * @type integer
- */
- public $Timelimit = 300;
-
- /**
- * The socket for the server connection.
- * @type resource
- */
- protected $smtp_conn;
-
- /**
- * Error message, if any, for the last call.
- * @type array
- */
- protected $error = array();
-
- /**
- * The reply the server sent to us for HELO.
- * If null, no HELO string has yet been received.
- * @type string|null
- */
- protected $helo_rply = null;
-
- /**
- * The set of SMTP extensions sent in reply to EHLO command.
- * Indexes of the array are extension names.
- * Value at index 'HELO' or 'EHLO' (according to command that was sent)
- * represents the server name. In case of HELO it is the only element of the array.
- * Other values can be boolean TRUE or an array containing extension options.
- * If null, no HELO/EHLO string has yet been received.
- * @type array|null
- */
- protected $server_caps = null;
-
- /**
- * The most recent reply received from the server.
- * @type string
- */
- protected $last_reply = '';
-
- /**
- * Output debugging info via a user-selected method.
- * @see SMTP::$Debugoutput
- * @see SMTP::$do_debug
- * @param string $str Debug string to output
- * @param integer $level The debug level of this message; see DEBUG_* constants
- * @return void
- */
- protected function edebug($str, $level = 0)
- {
- if ($level > $this->do_debug) {
- return;
- }
- //Avoid clash with built-in function names
- if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
- call_user_func($this->Debugoutput, $str, $this->do_debug);
- return;
- }
- switch ($this->Debugoutput) {
- case 'error_log':
- //Don't output, just log
- error_log($str);
- break;
- case 'html':
- //Cleans up output a bit for a better looking, HTML-safe output
- echo htmlentities(
- preg_replace('/[\r\n]+/', '', $str),
- ENT_QUOTES,
- 'UTF-8'
- )
- . "- -This demonstrates sending multiple email messages with binary attachments -from a MySQL database using multipart/alternative messages.
- -
-require 'PHPMailerAutoload.php';
-
-$mail = new PHPMailer();
-
-$mail->From = 'list@example.com';
-$mail->FromName = 'List manager';
-$mail->Host = 'smtp1.example.com;smtp2.example.com';
-$mail->Mailer = 'smtp';
-
-@mysqli_connect('localhost','root','password');
-@mysqli_select_db("my_company");
-$query = "SELECT full_name, email, photo FROM employee";
-$result = @mysqli_query($query);
-
-while ($row = mysqli_fetch_assoc($result))
-{
- // HTML body
- $body = "Hello <font size=\"4\">" . $row['full_name'] . "</font>, <p>";
- $body .= "<i>Your</i> personal photograph to this message.<p>";
- $body .= "Sincerely, <br>";
- $body .= "phpmailer List manager";
-
- // Plain text body (for mail clients that cannot read HTML)
- $text_body = 'Hello ' . $row['full_name'] . ", \n\n";
- $text_body .= "Your personal photograph to this message.\n\n";
- $text_body .= "Sincerely, \n";
- $text_body .= 'phpmailer List manager';
-
- $mail->Body = $body;
- $mail->AltBody = $text_body;
- $mail->addAddress($row['email'], $row['full_name']);
- $mail->addStringAttachment($row['photo'], 'YourPhoto.jpg');
-
- if(!$mail->send())
- echo "There has been a mail error sending to " . $row['email'] . "<br>";
-
- // Clear all addresses and attachments for next loop
- $mail->clearAddresses();
- $mail->clearAttachments();
-}
-
-- -
- -Extending classes with inheritance is one of the most -powerful features of object-oriented programming. It allows you to make changes to the -original class for your own personal use without hacking the original -classes, and it's very easy to do: - -
-Here's a class that extends the phpmailer class and sets the defaults
-for the particular site:
-PHP include file: my_phpmailer.php
-
- -
-require 'PHPMailerAutoload.php';
-
-class my_phpmailer extends PHPMailer {
- // Set default variables for all new objects
- public $From = 'from@example.com';
- public $FromName = 'Mailer';
- public $Host = 'smtp1.example.com;smtp2.example.com';
- public $Mailer = 'smtp'; // Alternative to isSMTP()
- public $WordWrap = 75;
-
- // Replace the default debug output function
- protected function edebug($msg) {
- print('My Site Error');
- print('Description:');
- printf('%s', $msg);
- exit;
- }
-
- //Extend the send function
- public function send() {
- $this->Subject = '[Yay for me!] '.$this->Subject;
- return parent::send()
- }
-
- // Create an additional function
- public function do_something($something) {
- // Place your new code here
- }
-}
-
-
-require 'my_phpmailer.php';
-
-// Instantiate your new class
-$mail = new my_phpmailer;
-
-// Now you only need to add the necessary stuff
-$mail->addAddress('josh@example.com', 'Josh Adams');
-$mail->Subject = 'Here is the subject';
-$mail->Body = 'This is the message body';
-$mail->addAttachment('c:/temp/11-10-00.zip', 'new_name.zip'); // optional name
-
-if(!$mail->send())
-{
- echo 'There was an error sending the message';
- exit;
-}
-
-echo 'Message was sent successfully';
-
-
-
diff --git a/download/phpmailer529/docs/faq.html b/download/phpmailer529/docs/faq.html
deleted file mode 100755
index 7033a142e..000000000
--- a/download/phpmailer529/docs/faq.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-\n"; - echo $example_code; - echo "\n\n"; - echo "\n
This example uses HTML.
-The PHPMailer image at the top has been embedded automatically.
-
This folder contains a collection of examples of using PHPMailer.
-When working on email sending code you'll find yourself worrying about what might happen if all these test emails got sent to your mailing list. The solution is to use a fake mail server, one that acts just like the real thing, but just doesn't actually send anything out. Some offer web interfaces, feedback, logging, the ability to return specific error codes, all things that are useful for testing error handling, authentication etc. Here's a selection of mail testing tools you might like to try:
-Before running these examples you'll need to rename them with '.php' extensions. They are supplied as '.phps' files which will usually be displayed with syntax highlighting by PHP instead of running them. This prevents potential security issues with running potential spam-gateway code if you happen to deploy these code examples on a live site - please don't do that! Similarly, don't leave your passwords in these files as they will be visible to the world!
-This script is a simple code generator - fill in the form and hit submit, and it will use when you entered to email you a message, and will also generate PHP code using your settings that you can copy and paste to use in your own apps. If you need to get going quickly, this is probably the best place to start.
-This script is a basic example which creates an email message from an external HTML file, creates a plain text body, sets various addresses, adds an attachment and sends the message. It uses PHP's built-in mail() function which is the simplest to use, but relies on the presence of a local mail server, something which is not usually available on Windows. If you find yourself in that situation, either install a local mail server, or use a remote one and send using SMTP instead.
-The same as the mail example, but shows how to use PHPMailer's optional exceptions for error handling.
-A simple example sending using SMTP with authentication.
-A simple example sending using SMTP without authentication.
-A simple example using sendmail. Sendmail is a program (usually found on Linux/BSD, OS X and other UNIX-alikes) that can be used to submit messages to a local mail server without a lengthy SMTP conversation. It's probably the fastest sending mechanism, but lacks some error reporting features. There are sendmail emulators for most popular mail servers including postfix, qmail, exim etc.
-Submitting email via Google's Gmail service is a popular use of PHPMailer. It's much the same as normal SMTP sending, just with some specific settings, namely using TLS encryption, authentication is enabled, and it connects to the SMTP submission port 587 on the smtp.gmail.com host. This example does all that.
-Before effective SMTP authentication mechanisms were available, it was common for ISPs to use POP-before-SMTP authentication. As it implies, you authenticate using the POP3 protocol (an older protocol now mostly replaced by the far superior IMAP), and then the SMTP server will allow send access from your IP address for a short while, usually 5-15 minutes. PHPMailer includes a POP3 protocol client, so it can carry out this sequence - it's just like a normal SMTP conversation (without authentication), but connects via POP first.
-This is a somewhat naïve example of sending similar emails to a list of different addresses. It sets up a PHPMailer instance using SMTP, then connects to a MySQL database to retrieve a list of recipients. The code loops over this list, sending email to each person using their info and marks them as sent in the database. It makes use of SMTP keepalive which saves reconnecting and re-authenticating between each message.
-This is an example showing how to use the SMTP class by itself (without PHPMailer) to check an SMTP connection.
-Most of these examples use the 'example.com' domain. This domain is reserved by IANA for illustrative purposes, as documented in RFC 2606. Don't use made-up domains like 'mydomain.com' or 'somedomain.com' in examples as someone, somewhere, probably owns them!
- - diff --git a/download/phpmailer529/examples/mail.phps b/download/phpmailer529/examples/mail.phps deleted file mode 100755 index 8e129f47d..000000000 --- a/download/phpmailer529/examples/mail.phps +++ /dev/null @@ -1,31 +0,0 @@ -setFrom('from@example.com', 'First Last'); -//Set an alternative reply-to address -$mail->addReplyTo('replyto@example.com', 'First Last'); -//Set who the message is to be sent to -$mail->addAddress('whoto@example.com', 'John Doe'); -//Set the subject line -$mail->Subject = 'PHPMailer mail() test'; -//Read an HTML message body from an external file, convert referenced images to embedded, -//convert HTML into a basic plain-text alternative body -$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); -//Replace the plain text body with one created manually -$mail->AltBody = 'This is a plain-text message body'; -//Attach an image file -$mail->addAttachment('images/phpmailer_mini.png'); - -//send the message, check for errors -if (!$mail->send()) { - echo "Mailer Error: " . $mail->ErrorInfo; -} else { - echo "Message sent!"; -} diff --git a/download/phpmailer529/examples/mailing_list.phps b/download/phpmailer529/examples/mailing_list.phps deleted file mode 100755 index 8644bb596..000000000 --- a/download/phpmailer529/examples/mailing_list.phps +++ /dev/null @@ -1,59 +0,0 @@ -isSMTP(); -$mail->Host = 'smtp.example.com'; -$mail->SMTPAuth = true; -$mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent, reduces SMTP overhead -$mail->Port = 25; -$mail->Username = 'yourname@example.com'; -$mail->Password = 'yourpassword'; -$mail->setFrom('list@example.com', 'List manager'); -$mail->addReplyTo('list@example.com', 'List manager'); - -$mail->Subject = "PHPMailer Simple database mailing list test"; - -//Same body for all messages, so set this before the sending loop -//If you generate a different body for each recipient (e.g. you're using a templating system), -//set it inside the loop -$mail->msgHTML($body); -//msgHTML also sets AltBody, but if you want a custom one, set it afterwards -$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; - -//Connect to the database and select the recipients from your mailing list that have not yet been sent to -//You'll need to alter this to match your database -$mysql = mysqli_connect('localhost', 'username', 'password'); -mysqli_select_db($mysql, 'mydb'); -$result = mysqli_query($mysql, 'SELECT full_name, email, photo FROM mailinglist WHERE sent = false'); - -foreach ($result as $row) { //This iterator syntax only works in PHP 5.4+ - $mail->addAddress($row['email'], $row['full_name']); - if (!empty($row['photo'])) { - $mail->addStringAttachment($row['photo'], 'YourPhoto.jpg'); //Assumes the image data is stored in the DB - } - - if (!$mail->send()) { - echo "Mailer Error (" . str_replace("@", "@", $row["email"]) . ') ' . $mail->ErrorInfo . '| '+this.getLineNumbersHtml(t)+" | ":"")+''+' '+n+" "+" | "+"
.*?)"+"(?"+t.end+")","sgi")}}},e}();typeof exports!="undefined"?exports.SyntaxHighlighter=SyntaxHighlighter:null
\ No newline at end of file
diff --git a/download/phpmailer529/examples/scripts/shLegacy.js b/download/phpmailer529/examples/scripts/shLegacy.js
deleted file mode 100755
index 35c582c97..000000000
--- a/download/phpmailer529/examples/scripts/shLegacy.js
+++ /dev/null
@@ -1,141 +0,0 @@
-var dp = {
- SyntaxHighlighter : {}
-};
-
-dp.SyntaxHighlighter = {
- parseParams: function(
- input,
- showGutter,
- showControls,
- collapseAll,
- firstLine,
- showColumns
- )
- {
- function getValue(list, name)
- {
- var regex = new XRegExp('^' + name + '\\[(?\\w+)\\]$', 'gi'),
- match = null
- ;
-
- for (var i = 0; i < list.length; i++)
- if ((match = regex.exec(list[i])) != null)
- return match.value;
-
- return null;
- };
-
- function defaultValue(value, def)
- {
- return value != null ? value : def;
- };
-
- function asString(value)
- {
- return value != null ? value.toString() : null;
- };
-
- var parts = input.split(':'),
- brushName = parts[0],
- options = {},
- straight = { 'true' : true }
- reverse = { 'true' : false },
- result = null,
- defaults = SyntaxHighlighter.defaults
- ;
-
- for (var i in parts)
- options[parts[i]] = 'true';
-
- showGutter = asString(defaultValue(showGutter, defaults.gutter));
- showControls = asString(defaultValue(showControls, defaults.toolbar));
- collapseAll = asString(defaultValue(collapseAll, defaults.collapse));
- showColumns = asString(defaultValue(showColumns, defaults.ruler));
- firstLine = asString(defaultValue(firstLine, defaults['first-line']));
-
- return {
- brush : brushName,
- gutter : defaultValue(reverse[options.nogutter], showGutter),
- toolbar : defaultValue(reverse[options.nocontrols], showControls),
- collapse : defaultValue(straight[options.collapse], collapseAll),
- // ruler : defaultValue(straight[options.showcolumns], showColumns),
- 'first-line' : defaultValue(getValue(parts, 'firstline'), firstLine)
- };
- },
-
- HighlightAll: function(
- name,
- showGutter /* optional */,
- showControls /* optional */,
- collapseAll /* optional */,
- firstLine /* optional */,
- showColumns /* optional */
- )
- {
- function findValue()
- {
- var a = arguments;
-
- for (var i = 0; i < a.length; i++)
- {
- if (a[i] === null)
- continue;
-
- if (typeof(a[i]) == 'string' && a[i] != '')
- return a[i] + '';
-
- if (typeof(a[i]) == 'object' && a[i].value != '')
- return a[i].value + '';
- }
-
- return null;
- };
-
- function findTagsByName(list, name, tagName)
- {
- var tags = document.getElementsByTagName(tagName);
-
- for (var i = 0; i < tags.length; i++)
- if (tags[i].getAttribute('name') == name)
- list.push(tags[i]);
- }
-
- var elements = [],
- highlighter = null,
- registered = {},
- propertyName = 'innerHTML'
- ;
-
- // for some reason IE doesn't find by name, however it does see them just fine by tag name...
- findTagsByName(elements, name, 'pre');
- findTagsByName(elements, name, 'textarea');
-
- if (elements.length === 0)
- return;
-
- for (var i = 0; i < elements.length; i++)
- {
- var element = elements[i],
- params = findValue(
- element.attributes['class'], element.className,
- element.attributes['language'], element.language
- ),
- language = ''
- ;
-
- if (params === null)
- continue;
-
- params = dp.SyntaxHighlighter.parseParams(
- params,
- showGutter,
- showControls,
- collapseAll,
- firstLine,
- showColumns
- );
-
- SyntaxHighlighter.highlight(params, element);
- }
- }
-};
diff --git a/download/phpmailer529/examples/send_file_upload.phps b/download/phpmailer529/examples/send_file_upload.phps
deleted file mode 100755
index 3919cbefe..000000000
--- a/download/phpmailer529/examples/send_file_upload.phps
+++ /dev/null
@@ -1,49 +0,0 @@
-setFrom('from@example.com', 'First Last');
- $mail->addAddress('whoto@example.com', 'John Doe');
- $mail->Subject = 'PHPMailer file sender';
- $mail->msgHTML("My message body");
- // Attach the uploaded file
- $mail->addAttachment($uploadfile, 'My uploaded file');
- if (!$mail->send()) {
- $msg = "Mailer Error: " . $mail->ErrorInfo;
- } else {
- $msg = "Message sent!";
- }
- } else {
- $msg = 'Failed to move file to ' . $uploadfile;
- }
-}
-?>
-
-
-
-
- PHPMailer Upload
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/download/phpmailer529/examples/sendmail.phps b/download/phpmailer529/examples/sendmail.phps
deleted file mode 100755
index a830e4952..000000000
--- a/download/phpmailer529/examples/sendmail.phps
+++ /dev/null
@@ -1,33 +0,0 @@
-isSendmail();
-//Set who the message is to be sent from
-$mail->setFrom('from@example.com', 'First Last');
-//Set an alternative reply-to address
-$mail->addReplyTo('replyto@example.com', 'First Last');
-//Set who the message is to be sent to
-$mail->addAddress('whoto@example.com', 'John Doe');
-//Set the subject line
-$mail->Subject = 'PHPMailer sendmail test';
-//Read an HTML message body from an external file, convert referenced images to embedded,
-//convert HTML into a basic plain-text alternative body
-$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));
-//Replace the plain text body with one created manually
-$mail->AltBody = 'This is a plain-text message body';
-//Attach an image file
-$mail->addAttachment('images/phpmailer_mini.png');
-
-//send the message, check for errors
-if (!$mail->send()) {
- echo "Mailer Error: " . $mail->ErrorInfo;
-} else {
- echo "Message sent!";
-}
diff --git a/download/phpmailer529/examples/smtp.phps b/download/phpmailer529/examples/smtp.phps
deleted file mode 100755
index 7c6b02396..000000000
--- a/download/phpmailer529/examples/smtp.phps
+++ /dev/null
@@ -1,54 +0,0 @@
-isSMTP();
-//Enable SMTP debugging
-// 0 = off (for production use)
-// 1 = client messages
-// 2 = client and server messages
-$mail->SMTPDebug = 2;
-//Ask for HTML-friendly debug output
-$mail->Debugoutput = 'html';
-//Set the hostname of the mail server
-$mail->Host = "mail.example.com";
-//Set the SMTP port number - likely to be 25, 465 or 587
-$mail->Port = 25;
-//Whether to use SMTP authentication
-$mail->SMTPAuth = true;
-//Username to use for SMTP authentication
-$mail->Username = "yourname@example.com";
-//Password to use for SMTP authentication
-$mail->Password = "yourpassword";
-//Set who the message is to be sent from
-$mail->setFrom('from@example.com', 'First Last');
-//Set an alternative reply-to address
-$mail->addReplyTo('replyto@example.com', 'First Last');
-//Set who the message is to be sent to
-$mail->addAddress('whoto@example.com', 'John Doe');
-//Set the subject line
-$mail->Subject = 'PHPMailer SMTP test';
-//Read an HTML message body from an external file, convert referenced images to embedded,
-//convert HTML into a basic plain-text alternative body
-$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));
-//Replace the plain text body with one created manually
-$mail->AltBody = 'This is a plain-text message body';
-//Attach an image file
-$mail->addAttachment('images/phpmailer_mini.png');
-
-//send the message, check for errors
-if (!$mail->send()) {
- echo "Mailer Error: " . $mail->ErrorInfo;
-} else {
- echo "Message sent!";
-}
diff --git a/download/phpmailer529/examples/smtp_check.phps b/download/phpmailer529/examples/smtp_check.phps
deleted file mode 100755
index c42ed0bea..000000000
--- a/download/phpmailer529/examples/smtp_check.phps
+++ /dev/null
@@ -1,40 +0,0 @@
-do_debug = SMTP::DEBUG_CONNECTION;
-
-try {
-//Connect to an SMTP server
- if ($smtp->connect('mail.example.com', 25)) {
- //Say hello
- if ($smtp->hello('localhost')) { //Put your host name in here
- //Authenticate
- if ($smtp->authenticate('username', 'password')) {
- echo "Connected ok!";
- } else {
- throw new Exception('Authentication failed: ' . $smtp->getLastReply());
- }
- } else {
- throw new Exception('HELO failed: '. $smtp->getLastReply());
- }
- } else {
- throw new Exception('Connect failed');
- }
-} catch (Exception $e) {
- echo 'SMTP error: '. $e->getMessage(), "\n";
-}
-//Whatever happened, close the connection.
-$smtp->quit(true);
diff --git a/download/phpmailer529/examples/smtp_no_auth.phps b/download/phpmailer529/examples/smtp_no_auth.phps
deleted file mode 100755
index b59029842..000000000
--- a/download/phpmailer529/examples/smtp_no_auth.phps
+++ /dev/null
@@ -1,50 +0,0 @@
-isSMTP();
-//Enable SMTP debugging
-// 0 = off (for production use)
-// 1 = client messages
-// 2 = client and server messages
-$mail->SMTPDebug = 2;
-//Ask for HTML-friendly debug output
-$mail->Debugoutput = 'html';
-//Set the hostname of the mail server
-$mail->Host = "mail.example.com";
-//Set the SMTP port number - likely to be 25, 465 or 587
-$mail->Port = 25;
-//Whether to use SMTP authentication
-$mail->SMTPAuth = false;
-//Set who the message is to be sent from
-$mail->setFrom('from@example.com', 'First Last');
-//Set an alternative reply-to address
-$mail->addReplyTo('replyto@example.com', 'First Last');
-//Set who the message is to be sent to
-$mail->addAddress('whoto@example.com', 'John Doe');
-//Set the subject line
-$mail->Subject = 'PHPMailer SMTP without auth test';
-//Read an HTML message body from an external file, convert referenced images to embedded,
-//convert HTML into a basic plain-text alternative body
-$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));
-//Replace the plain text body with one created manually
-$mail->AltBody = 'This is a plain-text message body';
-//Attach an image file
-$mail->addAttachment('images/phpmailer_mini.png');
-
-//send the message, check for errors
-if (!$mail->send()) {
- echo "Mailer Error: " . $mail->ErrorInfo;
-} else {
- echo "Message sent!";
-}
diff --git a/download/phpmailer529/examples/styles/shCore.css b/download/phpmailer529/examples/styles/shCore.css
deleted file mode 100755
index 3b26ae7e7..000000000
--- a/download/phpmailer529/examples/styles/shCore.css
+++ /dev/null
@@ -1,46 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
diff --git a/download/phpmailer529/examples/styles/shCoreDefault.css b/download/phpmailer529/examples/styles/shCoreDefault.css
deleted file mode 100755
index 3f15ebaad..000000000
--- a/download/phpmailer529/examples/styles/shCoreDefault.css
+++ /dev/null
@@ -1,77 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
-.syntaxhighlighter{background-color:white !important;}
-.syntaxhighlighter .line.alt1{background-color:white !important;}
-.syntaxhighlighter .line.alt2{background-color:white !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#e0e0e0 !important;}
-.syntaxhighlighter .line.highlighted.number{color:black !important;}
-.syntaxhighlighter table caption{color:black !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #6ce26c !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#6ce26c !important;color:white !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:blue !important;background:white !important;border:1px solid #6ce26c !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:blue !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:red !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#6ce26c !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:black !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#008200 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:blue !important;}
-.syntaxhighlighter .keyword{color:#006699 !important;}
-.syntaxhighlighter .preprocessor{color:gray !important;}
-.syntaxhighlighter .variable{color:#aa7700 !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#ff1493 !important;}
-.syntaxhighlighter .constants{color:#0066cc !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#006699 !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}
-.syntaxhighlighter .keyword{font-weight:bold !important;}
diff --git a/download/phpmailer529/examples/styles/shCoreDjango.css b/download/phpmailer529/examples/styles/shCoreDjango.css
deleted file mode 100755
index 19c5eb4e9..000000000
--- a/download/phpmailer529/examples/styles/shCoreDjango.css
+++ /dev/null
@@ -1,78 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
-.syntaxhighlighter{background-color:#0a2b1d !important;}
-.syntaxhighlighter .line.alt1{background-color:#0a2b1d !important;}
-.syntaxhighlighter .line.alt2{background-color:#0a2b1d !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#233729 !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:#f8f8f8 !important;}
-.syntaxhighlighter .gutter{color:#497958 !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #41a83e !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#41a83e !important;color:#0a2b1d !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#96dd3b !important;background:black !important;border:1px solid #41a83e !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#96dd3b !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:white !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#41a83e !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:#ffe862 !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#f8f8f8 !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#336442 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#9df39f !important;}
-.syntaxhighlighter .keyword{color:#96dd3b !important;}
-.syntaxhighlighter .preprocessor{color:#91bb9e !important;}
-.syntaxhighlighter .variable{color:#ffaa3e !important;}
-.syntaxhighlighter .value{color:#f7e741 !important;}
-.syntaxhighlighter .functions{color:#ffaa3e !important;}
-.syntaxhighlighter .constants{color:#e0e8ff !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#96dd3b !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#eb939a !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#91bb9e !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#edef7d !important;}
-.syntaxhighlighter .comments{font-style:italic !important;}
-.syntaxhighlighter .keyword{font-weight:bold !important;}
diff --git a/download/phpmailer529/examples/styles/shCoreEclipse.css b/download/phpmailer529/examples/styles/shCoreEclipse.css
deleted file mode 100755
index fc8c59dab..000000000
--- a/download/phpmailer529/examples/styles/shCoreEclipse.css
+++ /dev/null
@@ -1,80 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
-.syntaxhighlighter{background-color:white !important;}
-.syntaxhighlighter .line.alt1{background-color:white !important;}
-.syntaxhighlighter .line.alt2{background-color:white !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#c3defe !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:black !important;}
-.syntaxhighlighter .gutter{color:#787878 !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #d4d0c8 !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#d4d0c8 !important;color:white !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#3f5fbf !important;background:white !important;border:1px solid #d4d0c8 !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#3f5fbf !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#aa7700 !important;}
-.syntaxhighlighter .toolbar{color:#a0a0a0 !important;background:#d4d0c8 !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:#a0a0a0 !important;}
-.syntaxhighlighter .toolbar a:hover{color:red !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#3f5fbf !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#2a00ff !important;}
-.syntaxhighlighter .keyword{color:#7f0055 !important;}
-.syntaxhighlighter .preprocessor{color:#646464 !important;}
-.syntaxhighlighter .variable{color:#aa7700 !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#ff1493 !important;}
-.syntaxhighlighter .constants{color:#0066cc !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#7f0055 !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}
-.syntaxhighlighter .keyword{font-weight:bold !important;}
-.syntaxhighlighter .xml .keyword{color:#3f7f7f !important;font-weight:normal !important;}
-.syntaxhighlighter .xml .color1,.syntaxhighlighter .xml .color1 a{color:#7f007f !important;}
-.syntaxhighlighter .xml .string{font-style:italic !important;color:#2a00ff !important;}
diff --git a/download/phpmailer529/examples/styles/shCoreEmacs.css b/download/phpmailer529/examples/styles/shCoreEmacs.css
deleted file mode 100755
index 4fbd3254f..000000000
--- a/download/phpmailer529/examples/styles/shCoreEmacs.css
+++ /dev/null
@@ -1,76 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
-.syntaxhighlighter{background-color:black !important;}
-.syntaxhighlighter .line.alt1{background-color:black !important;}
-.syntaxhighlighter .line.alt2{background-color:black !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#2a3133 !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:#d3d3d3 !important;}
-.syntaxhighlighter .gutter{color:#d3d3d3 !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #990000 !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#990000 !important;color:black !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#ebdb8d !important;background:black !important;border:1px solid #990000 !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#ebdb8d !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#ff7d27 !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#990000 !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:#9ccff4 !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#d3d3d3 !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#ff7d27 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#ff9e7b !important;}
-.syntaxhighlighter .keyword{color:aqua !important;}
-.syntaxhighlighter .preprocessor{color:#aec4de !important;}
-.syntaxhighlighter .variable{color:#ffaa3e !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#81cef9 !important;}
-.syntaxhighlighter .constants{color:#ff9e7b !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:aqua !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#ebdb8d !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff7d27 !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#aec4de !important;}
diff --git a/download/phpmailer529/examples/styles/shCoreFadeToGrey.css b/download/phpmailer529/examples/styles/shCoreFadeToGrey.css
deleted file mode 100755
index 398d6ee8d..000000000
--- a/download/phpmailer529/examples/styles/shCoreFadeToGrey.css
+++ /dev/null
@@ -1,77 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
-.syntaxhighlighter{background-color:#121212 !important;}
-.syntaxhighlighter .line.alt1{background-color:#121212 !important;}
-.syntaxhighlighter .line.alt2{background-color:#121212 !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#2c2c29 !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:white !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #3185b9 !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#3185b9 !important;color:#121212 !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#3185b9 !important;background:black !important;border:1px solid #3185b9 !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#3185b9 !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#d01d33 !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#3185b9 !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:#96daff !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:white !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#696854 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#e3e658 !important;}
-.syntaxhighlighter .keyword{color:#d01d33 !important;}
-.syntaxhighlighter .preprocessor{color:#435a5f !important;}
-.syntaxhighlighter .variable{color:#898989 !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#aaaaaa !important;}
-.syntaxhighlighter .constants{color:#96daff !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#d01d33 !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#ffc074 !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#4a8cdb !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#96daff !important;}
-.syntaxhighlighter .functions{font-weight:bold !important;}
diff --git a/download/phpmailer529/examples/styles/shCoreMDUltra.css b/download/phpmailer529/examples/styles/shCoreMDUltra.css
deleted file mode 100755
index 87a3cc2b3..000000000
--- a/download/phpmailer529/examples/styles/shCoreMDUltra.css
+++ /dev/null
@@ -1,76 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
-.syntaxhighlighter{background-color:#222222 !important;}
-.syntaxhighlighter .line.alt1{background-color:#222222 !important;}
-.syntaxhighlighter .line.alt2{background-color:#222222 !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#253e5a !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:lime !important;}
-.syntaxhighlighter .gutter{color:#38566f !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#222222 !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#428bdd !important;background:black !important;border:1px solid #435a5f !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#428bdd !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:lime !important;}
-.syntaxhighlighter .toolbar{color:#aaaaff !important;background:#435a5f !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:#aaaaff !important;}
-.syntaxhighlighter .toolbar a:hover{color:#9ccff4 !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:lime !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#428bdd !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:lime !important;}
-.syntaxhighlighter .keyword{color:#aaaaff !important;}
-.syntaxhighlighter .preprocessor{color:#8aa6c1 !important;}
-.syntaxhighlighter .variable{color:aqua !important;}
-.syntaxhighlighter .value{color:#f7e741 !important;}
-.syntaxhighlighter .functions{color:#ff8000 !important;}
-.syntaxhighlighter .constants{color:yellow !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#aaaaff !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:red !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:yellow !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}
diff --git a/download/phpmailer529/examples/styles/shCoreMidnight.css b/download/phpmailer529/examples/styles/shCoreMidnight.css
deleted file mode 100755
index 3c02103ce..000000000
--- a/download/phpmailer529/examples/styles/shCoreMidnight.css
+++ /dev/null
@@ -1,76 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
-.syntaxhighlighter{background-color:#0f192a !important;}
-.syntaxhighlighter .line.alt1{background-color:#0f192a !important;}
-.syntaxhighlighter .line.alt2{background-color:#0f192a !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#253e5a !important;}
-.syntaxhighlighter .line.highlighted.number{color:#38566f !important;}
-.syntaxhighlighter table caption{color:#d1edff !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#0f192a !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#428bdd !important;background:black !important;border:1px solid #435a5f !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#428bdd !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#1dc116 !important;}
-.syntaxhighlighter .toolbar{color:#d1edff !important;background:#435a5f !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:#d1edff !important;}
-.syntaxhighlighter .toolbar a:hover{color:#8aa6c1 !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#d1edff !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#428bdd !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#1dc116 !important;}
-.syntaxhighlighter .keyword{color:#b43d3d !important;}
-.syntaxhighlighter .preprocessor{color:#8aa6c1 !important;}
-.syntaxhighlighter .variable{color:#ffaa3e !important;}
-.syntaxhighlighter .value{color:#f7e741 !important;}
-.syntaxhighlighter .functions{color:#ffaa3e !important;}
-.syntaxhighlighter .constants{color:#e0e8ff !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#b43d3d !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#f8bb00 !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:white !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}
diff --git a/download/phpmailer529/examples/styles/shCoreRDark.css b/download/phpmailer529/examples/styles/shCoreRDark.css
deleted file mode 100755
index f5b7b474a..000000000
--- a/download/phpmailer529/examples/styles/shCoreRDark.css
+++ /dev/null
@@ -1,76 +0,0 @@
-.syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}
-.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}
-.syntaxhighlighter.source{overflow:hidden !important;}
-.syntaxhighlighter .bold{font-weight:bold !important;}
-.syntaxhighlighter .italic{font-style:italic !important;}
-.syntaxhighlighter .line{white-space:pre !important;}
-.syntaxhighlighter table{width:100% !important;}
-.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}
-.syntaxhighlighter table td.code{width:100% !important;}
-.syntaxhighlighter table td.code .container{position:relative !important;}
-.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}
-.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}
-.syntaxhighlighter table td.code .line{padding:0 1em !important;}
-.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}
-.syntaxhighlighter.show{display:block !important;}
-.syntaxhighlighter.collapsed table{display:none !important;}
-.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}
-.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}
-.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}
-.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}
-.syntaxhighlighter .toolbar span.title{display:inline !important;}
-.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}
-.syntaxhighlighter .toolbar a.expandSource{display:none !important;}
-.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}
-.syntaxhighlighter.ie .toolbar{line-height:8px !important;}
-.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}
-.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}
-.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}
-.syntaxhighlighter.printing .line .content{color:black !important;}
-.syntaxhighlighter.printing .toolbar{display:none !important;}
-.syntaxhighlighter.printing a{text-decoration:none !important;}
-.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}
-.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}
-.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}
-.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}
-.syntaxhighlighter.printing .preprocessor{color:gray !important;}
-.syntaxhighlighter.printing .variable{color:#aa7700 !important;}
-.syntaxhighlighter.printing .value{color:#009900 !important;}
-.syntaxhighlighter.printing .functions{color:#ff1493 !important;}
-.syntaxhighlighter.printing .constants{color:#0066cc !important;}
-.syntaxhighlighter.printing .script{font-weight:bold !important;}
-.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}
-.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}
-.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}
-.syntaxhighlighter{background-color:#1b2426 !important;}
-.syntaxhighlighter .line.alt1{background-color:#1b2426 !important;}
-.syntaxhighlighter .line.alt2{background-color:#1b2426 !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#323e41 !important;}
-.syntaxhighlighter .line.highlighted.number{color:#b9bdb6 !important;}
-.syntaxhighlighter table caption{color:#b9bdb6 !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#1b2426 !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#5ba1cf !important;background:black !important;border:1px solid #435a5f !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#5ba1cf !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#5ce638 !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#435a5f !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:#e0e8ff !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#b9bdb6 !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#878a85 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#5ce638 !important;}
-.syntaxhighlighter .keyword{color:#5ba1cf !important;}
-.syntaxhighlighter .preprocessor{color:#435a5f !important;}
-.syntaxhighlighter .variable{color:#ffaa3e !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#ffaa3e !important;}
-.syntaxhighlighter .constants{color:#e0e8ff !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#5ba1cf !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#e0e8ff !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:white !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeAppleScript.css b/download/phpmailer529/examples/styles/shThemeAppleScript.css
deleted file mode 100755
index 7881bad44..000000000
--- a/download/phpmailer529/examples/styles/shThemeAppleScript.css
+++ /dev/null
@@ -1,21 +0,0 @@
-.syntaxhighlighter.applescript{background:white;font-size:1em;color:black;}
-.syntaxhighlighter.applescript div,.syntaxhighlighter.applescript code{font:1em/1.25 Verdana,sans-serif !important;}
-.syntaxhighlighter.applescript .code .line{overflow:hidden !important;}
-.syntaxhighlighter.applescript .code .line.highlighted{background:#b5d5ff !important;}
-.syntaxhighlighter.applescript .color1{color:#000000 !important;}
-.syntaxhighlighter.applescript .color2{color:#000000 !important;}
-.syntaxhighlighter.applescript .color3{color:#000000 !important;font-weight:bold !important;}
-.syntaxhighlighter.applescript .keyword{color:#000000 !important;font-weight:bold !important;}
-.syntaxhighlighter.applescript .color4{color:#0000ff !important;font-style:italic !important;}
-.syntaxhighlighter.applescript .comments{color:#4c4d4d !important;}
-.syntaxhighlighter.applescript .plain{color:#408000 !important;}
-.syntaxhighlighter.applescript .string{color:#000000 !important;}
-.syntaxhighlighter.applescript .commandNames{color:#0000ff !important;font-weight:bold !important;}
-.syntaxhighlighter.applescript .parameterNames{color:#0000ff !important;}
-.syntaxhighlighter.applescript .classes{color:#0000ff !important;font-style:italic !important;}
-.syntaxhighlighter.applescript .properties{color:#6c04d4 !important;}
-.syntaxhighlighter.applescript .enumeratedValues{color:#4a1e7f !important;}
-.syntaxhighlighter.applescript .additionCommandNames{color:#0016b0 !important;font-weight:bold !important;}
-.syntaxhighlighter.applescript .additionParameterNames{color:#0016b0 !important;}
-.syntaxhighlighter.applescript .additionClasses{color:#0016b0 !important;font-style:italic !important;}
-.syntaxhighlighter.applescript .spaces{display:inline-block;height:0 !important;font-size:1.75em !important;line-height:0 !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeDefault.css b/download/phpmailer529/examples/styles/shThemeDefault.css
deleted file mode 100755
index 8034517ee..000000000
--- a/download/phpmailer529/examples/styles/shThemeDefault.css
+++ /dev/null
@@ -1,31 +0,0 @@
-.syntaxhighlighter{background-color:white !important;}
-.syntaxhighlighter .line.alt1{background-color:white !important;}
-.syntaxhighlighter .line.alt2{background-color:white !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#e0e0e0 !important;}
-.syntaxhighlighter .line.highlighted.number{color:black !important;}
-.syntaxhighlighter table caption{color:black !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #6ce26c !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#6ce26c !important;color:white !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:blue !important;background:white !important;border:1px solid #6ce26c !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:blue !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:red !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#6ce26c !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:black !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#008200 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:blue !important;}
-.syntaxhighlighter .keyword{color:#006699 !important;}
-.syntaxhighlighter .preprocessor{color:gray !important;}
-.syntaxhighlighter .variable{color:#aa7700 !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#ff1493 !important;}
-.syntaxhighlighter .constants{color:#0066cc !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#006699 !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}
-.syntaxhighlighter .keyword{font-weight:bold !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeDjango.css b/download/phpmailer529/examples/styles/shThemeDjango.css
deleted file mode 100755
index 5cb724f90..000000000
--- a/download/phpmailer529/examples/styles/shThemeDjango.css
+++ /dev/null
@@ -1,32 +0,0 @@
-.syntaxhighlighter{background-color:#0a2b1d !important;}
-.syntaxhighlighter .line.alt1{background-color:#0a2b1d !important;}
-.syntaxhighlighter .line.alt2{background-color:#0a2b1d !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#233729 !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:#f8f8f8 !important;}
-.syntaxhighlighter .gutter{color:#497958 !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #41a83e !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#41a83e !important;color:#0a2b1d !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#96dd3b !important;background:black !important;border:1px solid #41a83e !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#96dd3b !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:white !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#41a83e !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:#ffe862 !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#f8f8f8 !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#336442 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#9df39f !important;}
-.syntaxhighlighter .keyword{color:#96dd3b !important;}
-.syntaxhighlighter .preprocessor{color:#91bb9e !important;}
-.syntaxhighlighter .variable{color:#ffaa3e !important;}
-.syntaxhighlighter .value{color:#f7e741 !important;}
-.syntaxhighlighter .functions{color:#ffaa3e !important;}
-.syntaxhighlighter .constants{color:#e0e8ff !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#96dd3b !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#eb939a !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#91bb9e !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#edef7d !important;}
-.syntaxhighlighter .comments{font-style:italic !important;}
-.syntaxhighlighter .keyword{font-weight:bold !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeEclipse.css b/download/phpmailer529/examples/styles/shThemeEclipse.css
deleted file mode 100755
index b089c5d7c..000000000
--- a/download/phpmailer529/examples/styles/shThemeEclipse.css
+++ /dev/null
@@ -1,34 +0,0 @@
-.syntaxhighlighter{background-color:white !important;}
-.syntaxhighlighter .line.alt1{background-color:white !important;}
-.syntaxhighlighter .line.alt2{background-color:white !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#c3defe !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:black !important;}
-.syntaxhighlighter .gutter{color:#787878 !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #d4d0c8 !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#d4d0c8 !important;color:white !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#3f5fbf !important;background:white !important;border:1px solid #d4d0c8 !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#3f5fbf !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#aa7700 !important;}
-.syntaxhighlighter .toolbar{color:#a0a0a0 !important;background:#d4d0c8 !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:#a0a0a0 !important;}
-.syntaxhighlighter .toolbar a:hover{color:red !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#3f5fbf !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#2a00ff !important;}
-.syntaxhighlighter .keyword{color:#7f0055 !important;}
-.syntaxhighlighter .preprocessor{color:#646464 !important;}
-.syntaxhighlighter .variable{color:#aa7700 !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#ff1493 !important;}
-.syntaxhighlighter .constants{color:#0066cc !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#7f0055 !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}
-.syntaxhighlighter .keyword{font-weight:bold !important;}
-.syntaxhighlighter .xml .keyword{color:#3f7f7f !important;font-weight:normal !important;}
-.syntaxhighlighter .xml .color1,.syntaxhighlighter .xml .color1 a{color:#7f007f !important;}
-.syntaxhighlighter .xml .string{font-style:italic !important;color:#2a00ff !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeEmacs.css b/download/phpmailer529/examples/styles/shThemeEmacs.css
deleted file mode 100755
index a3dcfc92b..000000000
--- a/download/phpmailer529/examples/styles/shThemeEmacs.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.syntaxhighlighter{background-color:black !important;}
-.syntaxhighlighter .line.alt1{background-color:black !important;}
-.syntaxhighlighter .line.alt2{background-color:black !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#2a3133 !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:#d3d3d3 !important;}
-.syntaxhighlighter .gutter{color:#d3d3d3 !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #990000 !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#990000 !important;color:black !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#ebdb8d !important;background:black !important;border:1px solid #990000 !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#ebdb8d !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#ff7d27 !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#990000 !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:#9ccff4 !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#d3d3d3 !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#ff7d27 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#ff9e7b !important;}
-.syntaxhighlighter .keyword{color:aqua !important;}
-.syntaxhighlighter .preprocessor{color:#aec4de !important;}
-.syntaxhighlighter .variable{color:#ffaa3e !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#81cef9 !important;}
-.syntaxhighlighter .constants{color:#ff9e7b !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:aqua !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#ebdb8d !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff7d27 !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#aec4de !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeFadeToGrey.css b/download/phpmailer529/examples/styles/shThemeFadeToGrey.css
deleted file mode 100755
index d0b1c93e0..000000000
--- a/download/phpmailer529/examples/styles/shThemeFadeToGrey.css
+++ /dev/null
@@ -1,31 +0,0 @@
-.syntaxhighlighter{background-color:#121212 !important;}
-.syntaxhighlighter .line.alt1{background-color:#121212 !important;}
-.syntaxhighlighter .line.alt2{background-color:#121212 !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#2c2c29 !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:white !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #3185b9 !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#3185b9 !important;color:#121212 !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#3185b9 !important;background:black !important;border:1px solid #3185b9 !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#3185b9 !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#d01d33 !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#3185b9 !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:#96daff !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:white !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#696854 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#e3e658 !important;}
-.syntaxhighlighter .keyword{color:#d01d33 !important;}
-.syntaxhighlighter .preprocessor{color:#435a5f !important;}
-.syntaxhighlighter .variable{color:#898989 !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#aaaaaa !important;}
-.syntaxhighlighter .constants{color:#96daff !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#d01d33 !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#ffc074 !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#4a8cdb !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#96daff !important;}
-.syntaxhighlighter .functions{font-weight:bold !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeMDUltra.css b/download/phpmailer529/examples/styles/shThemeMDUltra.css
deleted file mode 100755
index 6f712fd65..000000000
--- a/download/phpmailer529/examples/styles/shThemeMDUltra.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.syntaxhighlighter{background-color:#222222 !important;}
-.syntaxhighlighter .line.alt1{background-color:#222222 !important;}
-.syntaxhighlighter .line.alt2{background-color:#222222 !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#253e5a !important;}
-.syntaxhighlighter .line.highlighted.number{color:white !important;}
-.syntaxhighlighter table caption{color:lime !important;}
-.syntaxhighlighter .gutter{color:#38566f !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#222222 !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#428bdd !important;background:black !important;border:1px solid #435a5f !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#428bdd !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:lime !important;}
-.syntaxhighlighter .toolbar{color:#aaaaff !important;background:#435a5f !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:#aaaaff !important;}
-.syntaxhighlighter .toolbar a:hover{color:#9ccff4 !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:lime !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#428bdd !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:lime !important;}
-.syntaxhighlighter .keyword{color:#aaaaff !important;}
-.syntaxhighlighter .preprocessor{color:#8aa6c1 !important;}
-.syntaxhighlighter .variable{color:aqua !important;}
-.syntaxhighlighter .value{color:#f7e741 !important;}
-.syntaxhighlighter .functions{color:#ff8000 !important;}
-.syntaxhighlighter .constants{color:yellow !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#aaaaff !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:red !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:yellow !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeMidnight.css b/download/phpmailer529/examples/styles/shThemeMidnight.css
deleted file mode 100755
index e9c177e6e..000000000
--- a/download/phpmailer529/examples/styles/shThemeMidnight.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.syntaxhighlighter{background-color:#0f192a !important;}
-.syntaxhighlighter .line.alt1{background-color:#0f192a !important;}
-.syntaxhighlighter .line.alt2{background-color:#0f192a !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#253e5a !important;}
-.syntaxhighlighter .line.highlighted.number{color:#38566f !important;}
-.syntaxhighlighter table caption{color:#d1edff !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#0f192a !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#428bdd !important;background:black !important;border:1px solid #435a5f !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#428bdd !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#1dc116 !important;}
-.syntaxhighlighter .toolbar{color:#d1edff !important;background:#435a5f !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:#d1edff !important;}
-.syntaxhighlighter .toolbar a:hover{color:#8aa6c1 !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#d1edff !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#428bdd !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#1dc116 !important;}
-.syntaxhighlighter .keyword{color:#b43d3d !important;}
-.syntaxhighlighter .preprocessor{color:#8aa6c1 !important;}
-.syntaxhighlighter .variable{color:#ffaa3e !important;}
-.syntaxhighlighter .value{color:#f7e741 !important;}
-.syntaxhighlighter .functions{color:#ffaa3e !important;}
-.syntaxhighlighter .constants{color:#e0e8ff !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#b43d3d !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#f8bb00 !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:white !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeRDark.css b/download/phpmailer529/examples/styles/shThemeRDark.css
deleted file mode 100755
index 42d8710f5..000000000
--- a/download/phpmailer529/examples/styles/shThemeRDark.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.syntaxhighlighter{background-color:#1b2426 !important;}
-.syntaxhighlighter .line.alt1{background-color:#1b2426 !important;}
-.syntaxhighlighter .line.alt2{background-color:#1b2426 !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#323e41 !important;}
-.syntaxhighlighter .line.highlighted.number{color:#b9bdb6 !important;}
-.syntaxhighlighter table caption{color:#b9bdb6 !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#1b2426 !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:#5ba1cf !important;background:black !important;border:1px solid #435a5f !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:#5ba1cf !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:#5ce638 !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#435a5f !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:#e0e8ff !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#b9bdb6 !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#878a85 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#5ce638 !important;}
-.syntaxhighlighter .keyword{color:#5ba1cf !important;}
-.syntaxhighlighter .preprocessor{color:#435a5f !important;}
-.syntaxhighlighter .variable{color:#ffaa3e !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#ffaa3e !important;}
-.syntaxhighlighter .constants{color:#e0e8ff !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#5ba1cf !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#e0e8ff !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:white !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}
diff --git a/download/phpmailer529/examples/styles/shThemeVisualStudio.css b/download/phpmailer529/examples/styles/shThemeVisualStudio.css
deleted file mode 100755
index 8ed369f58..000000000
--- a/download/phpmailer529/examples/styles/shThemeVisualStudio.css
+++ /dev/null
@@ -1,31 +0,0 @@
-.syntaxhighlighter{background-color:white !important;}
-.syntaxhighlighter .line.alt1{background-color:white !important;}
-.syntaxhighlighter .line.alt2{background-color:white !important;}
-.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#e0e0e0 !important;}
-.syntaxhighlighter .line.highlighted.number{color:black !important;}
-.syntaxhighlighter table caption{color:black !important;}
-.syntaxhighlighter .gutter{color:#afafaf !important;}
-.syntaxhighlighter .gutter .line{border-right:3px solid #6ce26c !important;}
-.syntaxhighlighter .gutter .line.highlighted{background-color:#6ce26c !important;color:white !important;}
-.syntaxhighlighter.printing .line .content{border:none !important;}
-.syntaxhighlighter.collapsed{overflow:visible !important;}
-.syntaxhighlighter.collapsed .toolbar{color:blue !important;background:white !important;border:1px solid #6ce26c !important;}
-.syntaxhighlighter.collapsed .toolbar a{color:blue !important;}
-.syntaxhighlighter.collapsed .toolbar a:hover{color:red !important;}
-.syntaxhighlighter .toolbar{color:white !important;background:#6ce26c !important;border:none !important;}
-.syntaxhighlighter .toolbar a{color:white !important;}
-.syntaxhighlighter .toolbar a:hover{color:black !important;}
-.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}
-.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#008200 !important;}
-.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#d11010 !important;}
-.syntaxhighlighter .keyword{color:#006699 !important;}
-.syntaxhighlighter .preprocessor{color:gray !important;}
-.syntaxhighlighter .variable{color:#aa7700 !important;}
-.syntaxhighlighter .value{color:#009900 !important;}
-.syntaxhighlighter .functions{color:#ff1493 !important;}
-.syntaxhighlighter .constants{color:#0066cc !important;}
-.syntaxhighlighter .script{font-weight:bold !important;color:#006699 !important;background-color:none !important;}
-.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}
-.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}
-.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}
-.syntaxhighlighter .keyword{font-weight:bold !important;}
diff --git a/download/phpmailer529/examples/styles/wrapping.png b/download/phpmailer529/examples/styles/wrapping.png
deleted file mode 100755
index 6972c5e59..000000000
Binary files a/download/phpmailer529/examples/styles/wrapping.png and /dev/null differ
diff --git a/download/phpmailer529/extras/EasyPeasyICS.php b/download/phpmailer529/extras/EasyPeasyICS.php
deleted file mode 100755
index 1d50b0195..000000000
--- a/download/phpmailer529/extras/EasyPeasyICS.php
+++ /dev/null
@@ -1,148 +0,0 @@
-
- * @author Manuel Reinhard
- *
- * Built with inspiration from
- * http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355
- * History:
- * 2010/12/17 - Manuel Reinhard - when it all started
- * 2014 PHPMailer project becomes maintainer
- */
-
-/**
- * Class EasyPeasyICS.
- * Simple ICS data generator
- * @package phpmailer
- * @subpackage easypeasyics
- */
-class EasyPeasyICS
-{
- /**
- * The name of the calendar
- * @type string
- */
- protected $calendarName;
- /**
- * The array of events to add to this calendar
- * @type array
- */
- protected $events = array();
-
- /**
- * Constructor
- * @param string $calendarName
- */
- public function __construct($calendarName = "")
- {
- $this->calendarName = $calendarName;
- }
-
- /**
- * Add an event to this calendar.
- * @param string $start The start date and time as a unix timestamp
- * @param string $end The end date and time as a unix timestamp
- * @param string $summary A summary or title for the event
- * @param string $description A description of the event
- * @param string $url A URL for the event
- * @param string $uid A unique identifier for the event - generated automatically if not provided
- * @return array An array of event details, including any generated UID
- */
- public function addEvent($start, $end, $summary = '', $description = '', $url = '', $uid = '')
- {
- if (empty($uid)) {
- $uid = md5(uniqid(mt_rand(), true)) . '@EasyPeasyICS';
- }
- $event = array(
- 'start' => gmdate('Ymd', $start) . 'T' . gmdate('His', $start) . 'Z',
- 'end' => gmdate('Ymd', $end) . 'T' . gmdate('His', $end) . 'Z',
- 'summary' => $summary,
- 'description' => $description,
- 'url' => $url,
- 'uid' => $uid
- );
- $this->events[] = $event;
- return $event;
- }
-
- /**
- * @return array Get the array of events.
- */
- public function getEvents()
- {
- return $this->events;
- }
-
- /**
- * Clear all events.
- */
- public function clearEvents()
- {
- $this->events = array();
- }
-
- /**
- * Get the name of the calendar.
- * @return string
- */
- public function getName()
- {
- return $this->calendarName;
- }
-
- /**
- * Set the name of the calendar.
- * @param $name
- */
- public function setName($name)
- {
- $this->calendarName = $name;
- }
-
- /**
- * Render and optionally output a vcal string.
- * @param bool $output Whether to output the calendar data directly (the default).
- * @return string The complete rendered vlal
- */
- public function render($output = true)
- {
- //Add header
- $ics = 'BEGIN:VCALENDAR
-METHOD:PUBLISH
-VERSION:2.0
-X-WR-CALNAME:' . $this->calendarName . '
-PRODID:-//hacksw/handcal//NONSGML v1.0//EN';
-
- //Add events
- foreach ($this->events as $event) {
- $ics .= '
-BEGIN:VEVENT
-UID:' . $event['uid'] . '
-DTSTAMP:' . gmdate('Ymd') . 'T' . gmdate('His') . 'Z
-DTSTART:' . $event['start'] . '
-DTEND:' . $event['end'] . '
-SUMMARY:' . str_replace("\n", "\\n", $event['summary']) . '
-DESCRIPTION:' . str_replace("\n", "\\n", $event['description']) . '
-URL;VALUE=URI:' . $event['url'] . '
-END:VEVENT';
- }
-
- //Add footer
- $ics .= '
-END:VCALENDAR';
-
- if ($output) {
- //Output
- $filename = $this->calendarName;
- //Filename needs quoting if it contains spaces
- if (strpos($filename, ' ') !== false) {
- $filename = '"'.$filename.'"';
- }
- header('Content-type: text/calendar; charset=utf-8');
- header('Content-Disposition: inline; filename=' . $filename . '.ics');
- echo $ics;
- }
- return $ics;
- }
-}
diff --git a/download/phpmailer529/extras/README.md b/download/phpmailer529/extras/README.md
deleted file mode 100755
index dac79e05f..000000000
--- a/download/phpmailer529/extras/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-#PHPMailer Extras
-
-These classes provide optional additional functions to PHPMailer.
-
-These are not loaded by the PHPMailer autoloader, so in some cases you may need to `require` them yourself before using them.
-
-##EasyPeasyICS
-
-This class was originally written by Manuel Reinhard and provides a simple means of generating ICS/vCal files that are used in sending calendar events. PHPMailer does not use it directly, but you can use it to generate content appropriate for placing in the `Ical` property of PHPMailer. The PHPMailer project is now its official home as Manuel has given permission for that and is no longer maintaining it himself.
-
-##htmlfilter
-
-This class by Konstantin Riabitsev and Jim Jagielski implements HTML filtering to remove potentially malicious tags, such as `
diff --git a/java_generate/templates/generic.template.html b/java_generate/templates/generic.template.html
index a2fae4e9e..d8858a537 100644
--- a/java_generate/templates/generic.template.html
+++ b/java_generate/templates/generic.template.html
@@ -1,7 +1,7 @@
- :: \ Language (API) \ Processing 2+
+ :: \ Language (API) \ Processing 3+
@@ -23,13 +23,13 @@
-
- Processing Foundation
@@ -44,6 +44,12 @@
+
diff --git a/java_generate/templates/index.alphabetical.template.html b/java_generate/templates/index.alphabetical.template.html
index 0f865fac0..1c52fca5c 100644
--- a/java_generate/templates/index.alphabetical.template.html
+++ b/java_generate/templates/index.alphabetical.template.html
@@ -1,7 +1,7 @@
- Alphabetical Language Reference (API) \ Processing 2+
+ Alphabetical Language Reference (API) \ Processing 3+
@@ -28,6 +28,7 @@
p5.js
Processing.py
Processing for Android
+ Processing for Pi
- Processing Foundation
@@ -42,6 +43,12 @@
+
diff --git a/java_generate/templates/index.template.html b/java_generate/templates/index.template.html
index 2204a2ad0..12b460548 100644
--- a/java_generate/templates/index.template.html
+++ b/java_generate/templates/index.template.html
@@ -1,7 +1,7 @@
- Language Reference (API) \ Processing 2+
+ Language Reference (API) \ Processing 3+
@@ -27,6 +27,7 @@
- p5.js
- Processing.py
- Processing for Android
+ - Processing for Pi
- Processing Foundation
@@ -41,6 +42,12 @@
+
diff --git a/java_generate/templates/library.index.template.html b/java_generate/templates/library.index.template.html
index ee0d6a6cd..98c01d64e 100644
--- a/java_generate/templates/library.index.template.html
+++ b/java_generate/templates/library.index.template.html
@@ -1,7 +1,7 @@
- Video \ Libraries \ Processing 2+
+ Video \ Libraries \ Processing 3+
@@ -23,12 +23,13 @@
-
+
- Processing Foundation
@@ -83,7 +84,7 @@ Events
© Info
-
+
diff --git a/java_generate/templates/nav.web.template.html b/java_generate/templates/nav.web.template.html
index 010aeb9d9..43f41939c 100644
--- a/java_generate/templates/nav.web.template.html
+++ b/java_generate/templates/nav.web.template.html
@@ -1,32 +1,33 @@
\ No newline at end of file
diff --git a/javascript/site.js b/javascript/site.js
index 7fe7e2493..48c2f805a 100644
--- a/javascript/site.js
+++ b/javascript/site.js
@@ -1,5 +1,13 @@
$(function(){
+ // redirect download to support
+ $('.download [href*="download.processing.org"]').on('click', function (e) {
+ e.preventDefault()
+ window.open($(this).attr('href'))
+ window.location = '/download/support.html'
+ window.focus()
+ })
+
// sticky scroll
if(!Modernizr.touch){
$(window).scroll(function(){
@@ -97,3 +105,5 @@ function format_relative_time(time_ago) {
if ( time_ago.seconds > 1 ) return ' ' + time_ago.seconds + ' seconds ago';
return 'just now';
}
+
+
diff --git a/subscribe/index.php b/subscribe/index.php
index 09b856f39..a684a7fc8 100755
--- a/subscribe/index.php
+++ b/subscribe/index.php
@@ -94,9 +94,9 @@
Shop
»Forum
»GitHub
- »Issues
- »Wiki
- »FAQ
+ »Issues
+ »Wiki
+ »FAQ
»Twitter
»Facebook
diff --git a/templates/foundation-template.html b/templates/foundation-template.html
deleted file mode 100644
index a77864dac..000000000
--- a/templates/foundation-template.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
- title
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - Processing
- - p5.js
- - Processing.py
- - Processing for Android
-
-
-
-
-
- header
-
-
-
-
-
- navigation
-
-
-
-
- content_for_layout
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/templates/foundation-template.local.html b/templates/foundation-template.local.html
deleted file mode 100644
index 5a5f3167e..000000000
--- a/templates/foundation-template.local.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
- title
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/templates/foundation-template.nav.php b/templates/foundation-template.nav.php
deleted file mode 100644
index 24b967859..000000000
--- a/templates/foundation-template.nav.php
+++ /dev/null
@@ -1,65 +0,0 @@
- array('/', 0),
-
- 'Mission' => array('/mission/', 1),
-
- 'Projects' => array('/projects/', 2),
- 'People' => array('/people/', 3),
- 'Fellowships' => array('/fellowships/', 4),
- 'Reports' => array('/reports/', 5),
- 'Patrons' => array('/patrons/', 6),
- //'Donate' => array('/donate/', 7),
-
- //'Download' => array('/download/', 0),
-
- );
-
-
-function navigation($section = '')
-{
- global $lang;
- global $translation;
- //$tr = $translation->navigation; // Removed 22 Sep 2011 --CR
-
- // $abo = array('About', 'Overview', 'People', 'Foundation');
- //$ref = array('Reference', 'Language', 'A-Z', 'Libraries', 'Tools', 'Environment');
- //$learn = array('Learning', 'Tutorials', 'Basics', 'Topics', '3D', 'Library', 'Books');
- //$found = array('Overview', 'Mission', 'Projects', 'People', 'Fellowships', 'Reports', 'Patrons', 'Donate');
- $found = array('Overview', 'Mission', 'Projects', 'People', 'Fellowships', 'Reports', 'Patrons');
-
- $html = "\t\t\t".'\n";
-}
-
-function l($s, $c)
-{
- global $pages;
- return "$s";
- return "$s";
-}
-
-?>
diff --git a/templates/foundation-template.php b/templates/foundation-template.php
deleted file mode 100644
index f71cd33e1..000000000
--- a/templates/foundation-template.php
+++ /dev/null
@@ -1,290 +0,0 @@
-');
-define('REL_HEADER', '');
-define('HEADER_LINK', '');
-
-class Page
-{
- var $xhtml;
- var $lang;
- var $subtemplate = false;
- var $section;
-
- function Page($title = '', $section = '', $bodyid = '', $rel_path = '/')
- {
- $this->xhtml = new xhtml_page(TEMPLATEDIR.'foundation-template.html');
- $this->set('relpath', $rel_path);
- if (strcmp($rel_path, '/')) {
- $this->xhtml->set('header', REL_HEADER);
- } else {
- $this->xhtml->set('header', $section == 'Cover' ? HEADER : HEADER_LINK);
- $this->xhtml->set('header', $section == 'Overview2' ? HEADER : HEADER_LINK);
- }
- $this->section = $section;
- $this->xhtml->set('bodyid', ($bodyid == '') ? $section : $bodyid);
- $title = ($title == '') ? 'Processing Foundation' : $title . ' \ Processing Foundation';
- $this->xhtml->set('title', $title);
- $this->xhtml->set('navigation', navigation($section));
- }
-
- function set($key, $value)
- {
- $this->xhtml->set($key, $value);
- }
-
- function set_array($array)
- {
- foreach ($array as $key => $value) {
- $this->xhtml->set($key, $value);
- }
- }
-
- function subtemplate($file)
- {
- $piece = new xhtml_piece(TEMPLATEDIR.$file);
- $this->xhtml->set('content_for_layout', $piece->out());
- $this->subtemplate = true;
- }
-
- function content($content)
- {
- if (!$this->subtemplate) {
- $this->xhtml->set('content_for_layout', $content);
- } else {
- $this->xhtml->set('content', $content);
- }
- }
-
- function language($lang)
- {
- global $LANGUAGES;
- $this->lang = $lang;
- $this->xhtml->set('charset', $LANGUAGES[$lang][1]);
- $this->xhtml->set('lang', $lang);
- if ($lang != 'en') {
- #$this->xhtml->set('navigation', navigation_tr($this->section));
- $this->xhtml->set('navigation', navigation($this->section));
- }
- }
-
- function out()
- {
- if (!$this->lang) { $this->language('en'); }
- return $this->xhtml->out();
- }
-
- function set_rel_path($path = '')
- {
- $this->xhtml->set('relpath', $path);
- }
-}
-
-class ReferencePage
-{
- var $xhtml;
- var $lang;
- var $filepath;
-
- function ReferencePage(&$ref, $translation, $lang = 'en')
- {
- global $LANGUAGES;
-
- $this->filepath = 'reference/' . ($lang == 'en' ? '' : "$lang/") . $ref->name();
- $title = $ref->title() . ($lang == 'en' ? '' : " \ {$LANGUAGES[$lang][0]}") .' \ Language (API) \ Processing 2+';
-
- $xhtml = new xhtml_page(TEMPLATEDIR.'foundation-template.translation.html');
- $xhtml->set('header', HEADER_LINK);
- $xhtml->set('title', $title);
- $xhtml->set('bodyid', 'Langauge-'.$lang);
-
- $xhtml->set('navigation', ($lang == 'en') ? navigation('Language') : navigation('Language'));
-
- $piece = new xhtml_piece(TEMPLATEDIR.'foundation-template.reference.item.html');
- $xhtml->set('content_for_layout', $piece->out());
-
- $xhtml->set('reference_nav', reference_nav());
- $xhtml->set('language_nav', language_nav($lang));
-
- $xhtml->set('content', $ref->display());
- foreach ($translation->attributes as $key => $value) {
- $xhtml->set($key, $value);
- }
-
- foreach ($translation->meta as $key => $value) {
- $xhtml->set($key, $value);
- }
-
- $xhtml->set('updated', date('F d, Y h:i:sa T', filemtime(CONTENTDIR.'/'.$ref->filepath)));
-
- $this->xhtml = $xhtml;
- $this->language($lang);
- }
-
- function language($lang)
- {
- global $LANGUAGES;
- $this->lang = $lang;
- $this->xhtml->set('charset', $LANGUAGES[$lang][1]);
- $this->xhtml->set('lang', $lang);
- }
-
- function out()
- {
- return $this->xhtml->out();
- }
-
- function write()
- {
- writeFile($this->filepath, $this->xhtml->out());
- }
-}
-
-class LibReferencePage extends ReferencePage
-{
- function LibReferencePage(&$ref, $lib, $translation, $lang = 'en')
- {
- global $LANGUAGES;
-
- $this->langdir = 'reference/' . ($lang == 'en' ? '' : "$lang");
- $this->libsdir = $this->langdir . '/libraries';
- $this->libdir = $this->libsdir . "/$lib";
- $this->filepath = $this->libdir . '/' . $ref->name();
-
- $title = $ref->title() . ($lang == 'en' ? '' : " \ {$LANGUAGES[$lang][0]}") .' \ Language (API) \ Processing 2+';
-
- $xhtml = new xhtml_page(TEMPLATEDIR.'foundation-template.translation.html');
- $xhtml->set('header', HEADER_LINK);
- $xhtml->set('title', $title);
- $xhtml->set('bodyid', 'Library-ref');
- if ($lang == 'en') {
- $xhtml->set('navigation', navigation('Libraries'));
- } else {
- $xhtml->set('navigation', navigation_tr('Libraries'));
- }
-
- $piece = new xhtml_piece(TEMPLATEDIR.'foundation-template.reference.item.html');
- $xhtml->set('content_for_layout', $piece->out());
-
- $xhtml->set('reference_nav', library_nav($lib));
- $xhtml->set('language_nav', language_nav($lang));
-
- $xhtml->set('content', $ref->display());
-
- foreach ($translation->attributes as $key => $value) {
- $xhtml->set($key, $value);
- }
-
- foreach ($translation->meta as $key => $value) {
- $xhtml->set($key, $value);
- }
-
- //$xhtml->set('updated', date('F d, Y h:i:sa T', filemtime(CONTENTDIR.'/'.$ref->filepath)));
-
- $this->xhtml = $xhtml;
- $this->language($lang);
- }
-}
-
-class LocalPage extends Page
-{
- var $xhtml;
- var $lang = 'en';
- var $subtemplate = false;
-
- function LocalPage($title = '', $section = '', $bodyid = '', $rel_path = '')
- {
- $this->xhtml = new xhtml_page(TEMPLATEDIR.'foundation-template.local.html');
- $this->xhtml->set('header', '');
- $title = ($title == '') ? 'Processing 2+' : $title . ' \ Processing 2+';
- $this->xhtml->set('title', $title);
- $this->xhtml->set('navigation', local_nav($section, $rel_path));
- $this->set('relpath', $rel_path);
- $this->language('en');
- $this->xhtml->set('bodyid', ($bodyid == '') ? $section : $bodyid);
- }
-}
-
-class LocalReferencePage extends ReferencePage
-{
- var $xhtml;
- var $lang = 'en';
- var $filepath;
-
- function LocalReferencePage(&$ref, $translation, $lang = 'en', $rel_path = '')
- {
- $this->filepath = 'distribution/' . $ref->name();
- $title = $ref->title() .' \ Language (API) \ Processing 2+';
-
- $xhtml = new xhtml_page(TEMPLATEDIR.'foundation-template.local.html');
- $xhtml->set('header', '');
- $xhtml->set('title', $title);
- $xhtml->set('bodyid', 'Langauge');
- $xhtml->set('navigation', local_nav('Language'));
-
- $piece = new xhtml_piece(TEMPLATEDIR.'foundation-template.reference.item.html');
- $xhtml->set('content_for_layout', $piece->out());
-
- $xhtml->set('reference_nav', reference_nav());
- $xhtml->set('language_nav', language_nav($lang));
-
- $xhtml->set('content', $ref->display());
- foreach ($translation->attributes as $key => $value) {
- $xhtml->set($key, $value);
- }
-
- foreach ($translation->meta as $key => $value) {
- $xhtml->set($key, $value);
- }
-
- $xhtml->set('relpath', $rel_path);
- $xhtml->set('updated', date('F d, Y h:i:sa T', filemtime(CONTENTDIR.'/'.$ref->filepath)));
-
- $this->xhtml = $xhtml;
- $this->language($lang);
- }
-}
-
-class LocalLibReferencePage extends ReferencePage
-{
- function LocalLibReferencePage(&$ref, $lib, $translation, $rel_path = '../../')
- {
- global $LANGUAGES;
- $lang = 'en';
-
- $this->filepath = "distribution/libraries/$lib/" . $ref->name();
-
- $title = $ref->title() . "\\ $lib \\ Language (API) \\ Processing 2+";
-
- $xhtml = new xhtml_page(TEMPLATEDIR.'foundation-template.local.html');
- $xhtml->set('header', '');
- $xhtml->set('title', $title);
- $xhtml->set('bodyid', 'Library-ref');
-
- $xhtml->set('navigation', local_nav('Libraries', $rel_path));
-
- $piece = new xhtml_piece(TEMPLATEDIR.'foundation-template.reference.item.html');
- $xhtml->set('content_for_layout', $piece->out());
-
- $xhtml->set('reference_nav', library_nav($lib));
- $xhtml->set('language_nav', language_nav($lang));
-
- foreach ($translation->attributes as $key => $value) {
- $xhtml->set($key, $value);
- }
-
- foreach ($translation->meta as $key => $value) {
- $xhtml->set($key, $value);
- }
-
- $xhtml->set('content', $ref->display());
-
- $xhtml->set('updated', date('F d, Y h:i:sa T', filemtime(CONTENTDIR.'/'.$ref->filepath)));
- $xhtml->set('relpath', $rel_path);
- $this->xhtml = $xhtml;
- }
-}
-
-?>
diff --git a/templates/foundation-template.reference.item.html b/templates/foundation-template.reference.item.html
deleted file mode 100644
index 63f94d9f5..000000000
--- a/templates/foundation-template.reference.item.html
+++ /dev/null
@@ -1,43 +0,0 @@
-disclaimer contact
-
-content
-
-Updated on updated
-
-
-
-
-
\ No newline at end of file
diff --git a/templates/foundation-template.translation.html b/templates/foundation-template.translation.html
deleted file mode 100644
index 1bef912c5..000000000
--- a/templates/foundation-template.translation.html
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
- title
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/templates/template.cover.html b/templates/template.cover.html
index 84ce4be2c..4e776eb87 100755
--- a/templates/template.cover.html
+++ b/templates/template.cover.html
@@ -7,53 +7,34 @@
Download Processing
Browse Tutorials
Visit the Reference
-
-
-
- Processing is a flexible software sketchbook and a language for learning how to code within the context of the visual arts. Since 2001, Processing has promoted software literacy within the visual arts and visual literacy within technology. There are tens of thousands of students, artists, designers, researchers, and hobbyists who use Processing for learning and prototyping.
-
-
- - » Free to download and open source
- - » Interactive programs with 2D, 3D or PDF output
- - » OpenGL integration for accelerated 2D and 3D
- - » For GNU/Linux, Mac OS X, and Windows
- - » Over 100 libraries extend the core software
- - » Well documented, with many books available
-
-
-
+
+
+ Processing is a flexible software sketchbook and a language for learning how to code within the context of the visual arts. Since 2001, Processing has promoted software literacy within the visual arts and visual literacy within technology. There are tens of thousands of students, artists, designers, researchers, and hobbyists who use Processing for learning and prototyping.
+
+ - » Free to download and open source
+ - » Interactive programs with 2D, 3D, PDF, or SVG output
+ - » OpenGL integration for accelerated 2D and 3D
+ - » For GNU/Linux, Mac OS X, Windows, Android, and ARM
+ - » Over 100 libraries extend the core software
+ - » Well documented, with many books available
+
+
-
-
- New Books!
-
- The 2nd edition of Getting Started with Processing is here and it's updated for Processing 3. It's now in full color and there's a new chapter on working with data. The 2nd edition of the Processing Handbook is here too. Every chapter has been revised, and new chapters introduce more ways to work with data and geometry. New “synthesis” chapters offer discussion and worked examples of such topics as sketching with code, modularity, and algorithms.
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
-
- Exhibition
- exhibition
+
+ PCD 2020
+
+ The Processing Community Day (PCD) initiative is evolving. For 2020, we will offer a mentorship program for PCD Worldwide Organizers who are interested in learning from past community organizers and mentors. The goal is to help a diverse group of organizers launch a PCD in their local communities. Check out the PCD @ Worldwide site to learn more about starting or attending an event in 2020!
+
-
- To see more of what people are doing with Processing, check out these sites:
-
- » CreativeApplications.Net
- » For Your Processing
- » Processing Subreddit
- » OpenProcessing
- » Vimeo
-
- » Studio Sketchpad
+
+ To see more of what people are doing with Processing, check out these sites:
+ » CreativeApplications.Net
+ » OpenProcessing
+ » For Your Processing
+ » Processing Subreddit
+ » Vimeo
+ » Studio Sketchpad
-
- To contribute to the development, please visit
+
+ To contribute to Processing development, please visit
Processing on GitHub to read
instructions for downloading the code,
building from the source,
- reporting and tracking bugs, and
+ reporting and tracking bugs, and
creating libraries and tools.
-
-
Partners
- » Fathom
- » UCLA Arts Software Studio
- » NYU ITP
+ Partners
+ » Fathom
+ » NYU ITP
+ » UCLA Design Media Arts
-
- Mailing List
-
- If you are interested in receiving updates about Processing, submit your email through this form. Your email will only be used to send infrequent updates about Processing. It will not be sold or shared.
-
-
Contact
foundation@processing.org
diff --git a/templates/template.html b/templates/template.html
index b90627d71..b3836287a 100755
--- a/templates/template.html
+++ b/templates/template.html
@@ -27,6 +27,7 @@
- p5.js
- Processing.py
- Processing for Android
+ - Processing for Pi
- Processing Foundation
@@ -42,6 +43,13 @@
+
+
diff --git a/templates/template.nav.php b/templates/template.nav.php
index 40f2fcbf4..01dd329bd 100755
--- a/templates/template.nav.php
+++ b/templates/template.nav.php
@@ -8,11 +8,9 @@
'Learning' => array('/learning/', 1),
'Tutorials' => array('/tutorials/', 2),
- 'Examples' => array('/examples/', 2),
- # '3D' => array('/learning/3d/', 2),
- # 'Library' => array('/learning/library/', 2),
- 'Books' => array('/books/', 2),
- 'Handbook' => array('/handbook/', 2),
+ 'Examples' => array('/examples/', 2),
+ 'Books' => array('/books/', 2),
+ 'Handbook' => array('/handbook/', 2),
'Reference' => array('/reference/', 1),
@@ -23,6 +21,7 @@
'Environment' => array('/reference/environment/', 2),
'Download' => array('/download/', 1),
+ 'Donate' => array('/download/support.html', 1),
'Shop' => array('/shop/', 1),
@@ -32,7 +31,7 @@
'People' => array('/people/', 2),
'Foundation' => array('/foundation/', 2),
- 'FAQ' => array('http://wiki.processing.org/w/FAQ', 1),
+ 'FAQ' => array('https://github.com/processing/processing/wiki', 1),
);
@@ -56,9 +55,10 @@ function navigation($section = '')
$html .= "\t\t\t\t\t" . l('Cover', $section == 'Cover') . "
\n";
- $html .= "\t\t\t\t\t" . l('Download', $section == 'Download') . "
\n";
+ $html .= "\t\t\t\t\t" . l('Download', $section == 'Download') . "
\n";
+ $html .= "\t\t\t\t\t" . l('Donate', $section == 'Donate') . "
\n";
- $html .= "\t\t\t\t\t" . l('Exhibition', $section == 'Exhibition') . "
\n";
+ #$html .= "\t\t\t\t\t" . l('Exhibition', $section == 'Exhibition') . "
\n";
$html .= "\t\t\t\t\t" . l('Reference', $section == 'Reference') . "
\n";
$html .= "\t\t\t\t\t" . l('Libraries', $section == 'Libraries') . "
\n";
@@ -67,22 +67,23 @@ function navigation($section = '')
$html .= "\t\t\t\t\t" . l('Tutorials', $section == 'Tutorials') . "
\n";
$html .= "\t\t\t\t\t" . l('Examples', $section == 'Examples') . "
\n";
- $html .= "\t\t\t\t\t" . l('Books', $section == 'Books') . "
\n";
- $html .= "\t\t\t\t\t" . l('Handbook', $section == 'Handbook') . "
\n";
+ $html .= "\t\t\t\t\t" . l('Books', $section == 'Books') . "
\n";
+ #$html .= "\t\t\t\t\t" . l('Handbook', $section == 'Handbook') . "
\n";
$html .= "\t\t\t\t\t" . l('Overview', $section == 'Overview') . "
\n";
$html .= "\t\t\t\t\t" . l('People', $section == 'People') . "
\n";
# $html .= "\t\t\t\t\t" . l('Foundation', $section == 'Foundation') . "
\n";
- $html .= "\t\t\t\t\t" . l('Shop', $section == 'Shop') . "
\n";
+ #$html .= "\t\t\t\t\t" . l('Shop', $section == 'Shop') . "
\n";
- $html .= "\t\t\t\t\t" . "»Forum
\n";
+ $html .= "\t\t\t\t\t" . "»Forum
\n";
$html .= "\t\t\t\t\t" . "»GitHub
\n";
- $html .= "\t\t\t\t\t" . "»Issues
\n";
- $html .= "\t\t\t\t\t" . "»Wiki
\n";
- $html .= "\t\t\t\t\t" . "»FAQ
\n";
+ $html .= "\t\t\t\t\t" . "»Issues
\n";
+ $html .= "\t\t\t\t\t" . "»Wiki
\n";
+ $html .= "\t\t\t\t\t" . "»FAQ
\n";
$html .= "\t\t\t\t\t" . "»Twitter
\n";
- $html .= "\t\t\t\t\t" . "»Facebook
\n";
+ #$html .= "\t\t\t\t\t" . "»Facebook
\n";
+ $html .= "\t\t\t\t\t" . "»Medium
\n";
$html .= "\t\t\t\t\n";
diff --git a/templates/template.php b/templates/template.php
index d01db7566..f7ecfe4ea 100755
--- a/templates/template.php
+++ b/templates/template.php
@@ -92,7 +92,7 @@ function ReferencePage(&$ref, $translation, $lang = 'en')
global $LANGUAGES;
$this->filepath = 'reference/' . ($lang == 'en' ? '' : "$lang/") . $ref->name();
- $title = $ref->title() . ($lang == 'en' ? '' : " \ {$LANGUAGES[$lang][0]}") .' \ Language (API) \ Processing 2+';
+ $title = $ref->title() . ($lang == 'en' ? '' : " \ {$LANGUAGES[$lang][0]}") .' \ Language (API) \ Processing 3+';
$xhtml = new xhtml_page(TEMPLATEDIR.'template.translation.html');
$xhtml->set('header', HEADER_LINK);
@@ -152,7 +152,7 @@ function LibReferencePage(&$ref, $lib, $translation, $lang = 'en')
$this->libdir = $this->libsdir . "/$lib";
$this->filepath = $this->libdir . '/' . $ref->name();
- $title = $ref->title() . ($lang == 'en' ? '' : " \ {$LANGUAGES[$lang][0]}") .' \ Language (API) \ Processing 2+';
+ $title = $ref->title() . ($lang == 'en' ? '' : " \ {$LANGUAGES[$lang][0]}") .' \ Language (API) \ Processing 3+';
$xhtml = new xhtml_page(TEMPLATEDIR.'template.translation.html');
$xhtml->set('header', HEADER_LINK);
@@ -197,7 +197,7 @@ function LocalPage($title = '', $section = '', $bodyid = '', $rel_path = '')
{
$this->xhtml = new xhtml_page(TEMPLATEDIR.'template.local.html');
$this->xhtml->set('header', '');
- $title = ($title == '') ? 'Processing 2+' : $title . ' \ Processing 2+';
+ $title = ($title == '') ? 'Processing 3+' : $title . ' \ Processing 3+';
$this->xhtml->set('title', $title);
$this->xhtml->set('navigation', local_nav($section, $rel_path));
$this->set('relpath', $rel_path);
@@ -215,7 +215,7 @@ class LocalReferencePage extends ReferencePage
function LocalReferencePage(&$ref, $translation, $lang = 'en', $rel_path = '')
{
$this->filepath = 'distribution/' . $ref->name();
- $title = $ref->title() .' \ Language (API) \ Processing 2+';
+ $title = $ref->title() .' \ Language (API) \ Processing 3+';
$xhtml = new xhtml_page(TEMPLATEDIR.'template.local.html');
$xhtml->set('header', '');
@@ -255,7 +255,7 @@ function LocalLibReferencePage(&$ref, $lib, $translation, $rel_path = '../../')
$this->filepath = "distribution/libraries/$lib/" . $ref->name();
- $title = $ref->title() . "\\ $lib \\ Language (API) \\ Processing 2+";
+ $title = $ref->title() . "\\ $lib \\ Language (API) \\ Processing 3+";
$xhtml = new xhtml_page(TEMPLATEDIR.'template.local.html');
$xhtml->set('header', '');
diff --git a/templates/template.reference.item.html b/templates/template.reference.item.html
index 3cc4271cb..cfbe6ec45 100755
--- a/templates/template.reference.item.html
+++ b/templates/template.reference.item.html
@@ -7,7 +7,7 @@