Merge branch 'msg_network' of ssh://numinibsd/git/base/enigma-bbs into msg_network

This commit is contained in:
Bryan Ashby 2016-03-23 21:01:01 -06:00
commit 686573e362
60 changed files with 240 additions and 125 deletions

View File

@ -200,7 +200,13 @@ function startListening(cb) {
}
const moduleInst = new module.getModule();
const server = moduleInst.createServer();
let server;
try {
server = moduleInst.createServer();
} catch(e) {
logger.log.warn(e, 'Exception caught creating server!');
return;
}
// :TODO: handle maxConnections, e.g. conf.maxConnections

View File

@ -192,7 +192,7 @@ function getDefaultConfig() {
},
ssh : {
port : 8889,
enabled : true,
enabled : false, // defualt to false as PK/pass in config.hjson are required
//
// Private key in PEM format

View File

@ -169,8 +169,10 @@ exports.PacketHeader = PacketHeader;
// * Writeup on differences between type 2, 2.2, and 2+:
// http://walon.org/pub/fidonet/FTSC-nodelists-etc./pkt-types.txt
//
function Packet() {
function Packet(options) {
var self = this;
this.options = options || {};
this.parsePacketHeader = function(packetBuffer, cb) {
assert(Buffer.isBuffer(packetBuffer));
@ -574,6 +576,10 @@ function Packet() {
if(messageBodyData.tearLine) {
msg.meta.FtnProperty.ftn_tear_line = messageBodyData.tearLine;
if(self.options.keepTearAndOrigin) {
msg.message += `\r\n${messageBodyData.tearLine}\r\n`;
}
}
if(messageBodyData.seenBy.length > 0) {
@ -586,6 +592,10 @@ function Packet() {
if(messageBodyData.originLine) {
msg.meta.FtnProperty.ftn_origin = messageBodyData.originLine;
if(self.options.keepTearAndOrigin) {
msg.message += `${messageBodyData.originLine}\r\n`;
}
}
const nextBuf = packetBuffer.slice(read);

View File

@ -69,6 +69,8 @@ function getSortedAvailMessageConferences(client, options) {
// Return an *object* of available areas within |confTag|
function getAvailableMessageAreasByConfTag(confTag, options) {
options = options || {};
// :TODO: confTag === "" then find default
if(_.has(Config.messageConferences, [ confTag, 'areas' ])) {
const areas = Config.messageConferences[confTag].areas;

View File

@ -266,24 +266,21 @@ function MultiLineEditTextView(options) {
}
return lines;
};
this.getOutputText = function(startIndex, endIndex, includeEol) {
var lines = self.getTextLines(startIndex, endIndex);
//
// Convert lines to contiguous string -- all expanded
// tabs put back to single '\t' characters.
//
var text = '';
var re = new RegExp('\\t{1,' + (self.tabWidth) + '}', 'g');
for(var i = 0; i < lines.length; ++i) {
text += lines[i].text.replace(re, '\t');
if(includeEol && lines[i].eol) {
text += '\n';
}
}
return text;
};
this.getOutputText = function(startIndex, endIndex, eolMarker) {
let lines = self.getTextLines(startIndex, endIndex);
let text = '';
var re = new RegExp('\\t{1,' + (self.tabWidth) + '}', 'g');
lines.forEach(line => {
text += line.text.replace(re, '\t');
if(eolMarker && line.eol) {
text += eolMarker;
}
});
return text;
}
this.getContiguousText = function(startIndex, endIndex, includeEol) {
var lines = self.getTextLines(startIndex, endIndex);
@ -1018,7 +1015,7 @@ MultiLineEditTextView.prototype.addText = function(text) {
};
MultiLineEditTextView.prototype.getData = function() {
return this.getOutputText(0, this.textLines.length, true);
return this.getOutputText(0, this.textLines.length, '\r\n');
};
MultiLineEditTextView.prototype.setPropertyValue = function(propName, value) {

View File

@ -806,7 +806,9 @@ function FTNMessageScanTossModule() {
this.importMessagesFromPacketFile = function(packetPath, password, cb) {
let packetHeader;
new ftnMailPacket.Packet().read(packetPath, (entryType, entryData, next) => {
const packetOpts = { keepTearAndOrigin : true };
new ftnMailPacket.Packet(packetOpts).read(packetPath, (entryType, entryData, next) => {
if('header' === entryType) {
packetHeader = entryData;

View File

@ -235,7 +235,8 @@ SSHServerModule.prototype.createServer = function() {
privateKey : fs.readFileSync(Config.servers.ssh.privateKeyPem),
passphrase : Config.servers.ssh.privateKeyPass,
ident : 'enigma-bbs-' + enigVersion + '-srv',
// Note that sending 'banner' breaks at least EtherTerm!
// Note that sending 'banner' breaks at least EtherTerm!
debug : function debugSsh(dbgLine) {
if(true === Config.servers.ssh.traceConnections) {
Log.trace('SSH: ' + dbgLine);

View File

@ -21,5 +21,90 @@ general: {
}
```
#### A Sample Configuration
Below is a **sample** `config.hjson` illustrating various (but not all!) elements that can be configured / tweaked.
```hjson
{
general: {
boardName: A Sample BBS
}
defaults: {
theme: super-fancy-theme
}
preLoginTheme: luciano_blocktronics
messageConferences: {
local_general: {
name: Local
desc: Local Discussions
default: true
areas: {
local_enigma_dev: {
name: ENiGMA 1/2 Development
desc: Discussion related to development and features of ENiGMA 1/2!
default: true
}
}
}
agoranet: {
name: Agoranet
desc: This network is for blatant exploitation of the greatest BBS scene art group ever.. ACiD.
areas: {
agoranet_bbs: {
name: BBS Discussion
desc: Discussion related to BBSs
}
}
}
}
messageNetworks: {
ftn: {
areas: {
agoranet_bbs: { /* hey kids, this matches above! */
// oh oh oh, and this one pairs up with a network below
network: agoranet
tag: AGN_BBS
uplinks: "46:1/100"
}
}
networks: {
agoranet: {
localAddress: "46:3/102"
}
}
}
}
scannerTossers: {
ftn_bso: {
schedule: {
import: every 1 hours or @watch:/home/enigma/bink/watchfile.txt
export: every 1 hours or @immediate
}
defaultZone: 46
defaultNetwork: agoranet
nodes: {
"46:*": {
archiveType: ZIP
encoding: utf8
}
}
}
}
}
```
### Menus
TODO: Documentation on menu.hjson, etc.

View File

@ -7,37 +7,45 @@ FTN networks are configured under the `messageNetworks::ftn` section of `config.
### Networks
The `networks` section contains a sub section for network(s) you wish you join your board with. Each entry's key name can be referenced elsewhere in `config.hjson` for FTN oriented configurations.
Members:
**Members**:
* `localAddress` (required): FTN address of **your local system**
Example:
**Example**:
```hjson
{
networks: {
agoranet: {
localAddress: "46:3/102"
messageNetworks: {
ftn: {
networks: {
agoranet: {
localAddress: "46:3/102"
}
}
}
}
}
```
### Areas
The `areas` section defines a mapping of local **area tags** to a message network (from `networks` described previously), a FTN area tag, and remote uplink address(s). This section can be thought of similar to the *AREAS.BBS* file used by other BBS packages.
The `areas` section describes a mapping of local **area tags** found in your `messageConferences` to a message network (from `networks` described previously), a FTN specific area tag, and remote uplink address(s). This section can be thought of similar to the *AREAS.BBS* file used by other BBS packages.
Members:
When importing, messages will be placed in the local area that matches key under `areas`.
**Members**:
* `network` (required): Associated network from the `networks` section
* `tag` (required): FTN area tag
* `uplinks`: An array of FTN address uplink(s) for this network
Example:
**Example**:
```hjson
{
ftn: {
areas: {
agoranet_bbs: {
network: agoranet
tag: AGN_BBS
uplinks: "46:1/100"
messageNetworks: {
ftn: {
areas: {
agoranet_bbs: { /* found within messageConferences */
network: agoranet
tag: AGN_BBS
uplinks: "46:1/100"
}
}
}
}
@ -47,7 +55,7 @@ Example:
### BSO Import / Export
The scanner/tosser module `ftn_bso` provides **B**inkley **S**tyle **O**utbound (BSO) import/toss & scan/export of messages EchoMail and NetMail messages. Configuration is supplied in `config.hjson` under `scannerTossers::ftn_bso`.
Members:
**Members**:
* `defaultZone` (required): Sets the default BSO outbound zone
* `defaultNetwork` (optional): Sets the default network name from `messageNetworks::ftn::networks`. **Required if more than one network is defined**.
* `paths` (optional): Override default paths set by the system. This section may contain `outbound`, `inbound`, and `secInbound`.
@ -61,22 +69,24 @@ The `nodes` section defines how to export messages for one or more uplinks.
A node entry starts with a FTN style address (up to 5D) **as a key** in `config.hjson`. This key may contain wildcard(s) for net/zone/node/point/domain.
Members:
**Members**:
* `packetType` (optional): `2`, `2.2`, or `2+`. Defaults to `2+` for modern mailer compatiability
* `packetPassword` (optional): Password for the packet
* `encoding` (optional): Encoding to use for message bodies; Defaults to `utf-8`
* `archiveType` (optional): Specifies the archive type for ArcMail bundles. Must be a valid archiver name such as `zip` (See archiver configuration)
Example:
**Example**:
```hjson
{
ftn_bso: {
nodes: {
"46:*: {
packetType: 2+
packetPassword: mypass
encoding: cp437
archiveType: zip
scannerTossers: {
ftn_bso: {
nodes: {
"46:*: {
packetType: 2+
packetPassword: mypass
encoding: cp437
archiveType: zip
}
}
}
}
@ -86,19 +96,21 @@ Example:
#### Scheduling
Schedules can be defined for importing and exporting via `import` and `export` under `schedule`. Each entry is allowed a "free form" text and/or special indicators for immediate export or watch file triggers.
* `@immediate`: Currently only makes sense for exporting: A message will be immediately exported if this trigger is defined in a schedule.
* `@watch:/path/to/file`: This trigger watches the path specified for changes and will trigger an import or export when such events occur.
* `@immediate`: A message will be immediately exported if this trigger is defined in a schedule. Only used for `export`.
* `@watch:/path/to/file`: This trigger watches the path specified for changes and will trigger an import or export when such events occur. Only used for `import`.
* Free form text can be things like `at 5:00 pm` or `every 2 hours`.
See [Later text parsing documentation](http://bunkat.github.io/later/parsers.html#text) for more information.
Example:
**Example**:
```hjson
{
ftn_bso: {
schedule: {
import: every 1 hours or @watch:/path/to/watchfile.ext
export: every 1 hours or @immediate
scannerTossers: {
ftn_bso: {
schedule: {
import: every 1 hours or @watch:/path/to/watchfile.ext
export: every 1 hours or @immediate
}
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -1,19 +1,19 @@
 ーーーーーーーーーワイワワ  ー  ワワ 
 ーーーーーー ワワ゚ロロロイロロロロロ゚  ーー  ーーー ーーーー ー ワワワ゚゚゚ワワイロロロロロ゚
ーワワワ゚゚゙ロロロロイイロン ーー  ワワワ ワワ ーワワワ゚゚ロイイロロン
゚ワワワロロロイロ  ーロロロイイイアアワワワ゚゚ロロロロイロ゚ロイイイイアワワワイイイイーー ーー゙ロロロロロイ
 ゙ロイイロロロン゙ロイイアアアーン イアワワーア゚ ゙イイイイロン ゙イイアアアアアイイイアアア゙イイロロロン
ロロロロイイ゚     イイアアーーーロロー ーーーーン  アアアイイ イイアアーー ーアアアーーーーアアイイロン  
ーーイロイイアーーーー ー  ゚゚゚ーーロロヷーーーーアアーー ーー ーー ーーアア ゙ ーアーーーー゙ ーーーーーーー ーー ー ーーーーーアアイーー   ー゙イアアーー ワワ    ーーアアイロ  ゙アアーーー  ーーーアア ゙ーーーーアン ワ ゙ロ ーーアア 
ワ ゙アーー ーーン  ワ ワロロワワワ ワロイイイロロン゙ワイ゚ ゙ロイイアーー ーーアアアア ワ アアアアイロ ゙ロワロロイロ ゙ロロロロー  ゙ワ 
ーン ー ーーアイン ーーロワ ロロイイロロロロロロイロロイン ーー ゚゚゚゚ロイアア゚゙アアイイ ゙ーン ロイイロロン ローーロロン ーーーーロロン ロロー
゚  ーーーアアイイ ゚゚イ゚ ゙ロロロロロロイロロロロロロイ ゚゚゚イ ゚゚ イイロン ゚イ゚ ゙ロイロイイ ワワワ ゚ ゙アアーーーン ゚イ゚
゙アアアイイロン  ロロロロロロロロロロロロロロ゚゚ロロイロ゚゚ ゚゚゚゚゚ ロイイアアアア
ロイイロロロロ ゙ロロロロロイロ ロ゚゚ ゙イワロロイイイロン
 ワワ゚゚ ゚゚゚ワワワ ロロロロイ゚ ワワロロロロ゙ロロイロロ 
 ーー ゚゚゚゚゚ーーー ーー enigmaォbbs softロロロイイロンー ゙ロロロロイ ーー
dangermouse ーーロイロロロロロイロイロ ー
  ーー  ロイロロロロワワワワ゚゚゚゚゚゚゚゚ワワワ
゙ロロ゚゚ーーーーー
 ー ゚ ーーーーーーーーーー
 ーーーーーーーーーワイワワ  ー  ワワ 
 ーーーーーー ワワ゚ロロロイロロロロロ゚  ーー  ーーー ーーーー ー ワワワ゚゚゚ワワイロロロロロ゚
ーワワワ゚゚゙ロロロロイイロン ーー  ワワワ ワワ ーワワワ゚゚ロイイロロン
゚ワワワロロロイロ  ーロロロイイイアアワワワ゚゚ロロロロイロ゚ロイイイイアワワワイイイイーー ーー゙ロロロロロイ
 ゙ロイイロロロン゙ロイイアアアーン イアワワーア゚ ゙イイイイロン ゙イイアアアアアイイイアアア゙イイロロロン
ロロロロイイ゚     イイアアーーーロロー ーーーーン  アアアイイ イイアアーー ーアアアーーーーアアイイロン  
ーーイロイイアーーーー ー  ゚゚゚ーーロロヷーーーーアアーー ーー ーー ーーアア ゙ ーアーーーー゙ ーーーーーーー ーー ー ーーーーーアアイーー   ー゙イアアーー ワワ    ーーアアイロ  ゙アアーーー  ーーーアア ゙ーーーーアン ワ ゙ロ ーーアア 
ワ ゙アーー ーーン  ワ ワロロワワワ ワロイイイロロン゙ワイ゚ ゙ロイイアーー ーーアアアア ワ アアアアイロ ゙ロワロロイロ ゙ロロロロー  ゙ワ 
ーン ー ーーアイン ーーロワ ロロイイロロロロロロイロロイン ーー ゚゚゚゚ロイアア゚゙アアイイ ゙ーン ロイイロロン ローーロロン ーーーーロロン ロロー
゚  ーーーアアイイ ゚゚イ゚ ゙ロロロロロロイロロロロロロイ ゚゚゚イ ゚゚ イイロン ゚イ゚ ゙ロイロイイ ワワワ ゚ ゙アアーーーン ゚イ゚
゙アアアイイロン  ロロロロロロロロロロロロロロ゚゚ロロイロ゚゚ ゚゚゚゚゚ ロイイアアアア
ロイイロロロロ ゙ロロロロロイロ ロ゚゚ ゙イワロロイイイロン
 ワワ゚゚ ゚゚゚ワワワ ロロロロイ゚ ワワロロロロ゙ロロイロロ 
 ーー ゚゚゚゚゚ーーー ーー enigmaォbbs softロロロイイロンー ゙ロロロロイ ーー
dangermouse ーーロイロロロロロイロイロ ー
  ーー  ロイロロロロワワワワ゚゚゚゚゚゚゚゚ワワワ
゙ロロ゚゚ーーーーー
 ー ゚ ーーーーーーーーーー


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,52 +1,52 @@
You should never see this!
... nor this
[?33h
 fONT tEST
 ~~~~~~~~~
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
0 |NUL|  |  |  |  |  |  |  |BS |HT |LF | | |CR |  |  
1 |  |  |  |  |  |  |  |  |  |  |EOF|ESC|  |  |  |  
2 | | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / 
3 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? 
---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
4 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O 
5 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ 
6 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o 
7 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ |  
---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
8 | € | <20> | | ƒ | „ | … | † | ‡ | ˆ | ‰ | Š | | Œ | <20> | Ž | <20> 
9 | <20> | | | “ | ” | • | | — | ˜ | ™ | š | | œ | <20> | ž | Ÿ 
A |   | ¡ | ¢ | £ | ¤ | ¥ | ¦ | § | ¨ | © | ª | « | ¬ | ­ | ® | ¯ 
B | ° | ± | ² | ³ | ´ | µ | ¶ | · | ¸ | ¹ | º | » | ¼ | ½ | ¾ | ¿ 
---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
C | À | Á |  | à | Ä | Å | Æ | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï 
D | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß 
E | à | á | â | ã | ä | å | æ | ç | è | é | ê | ë | ì | í | î | ï 
F | ð | ñ | ò | ó | ô | õ | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ 
 cOLOR tEST
 ~~~~~~~~~~
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û

You should never see this!
... nor this
[?33h
 fONT tEST
 ~~~~~~~~~
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
0 |NUL|  |  |  |  |  |  |  |BS |HT |LF | | |CR |  |  
1 |  |  |  |  |  |  |  |  |  |  |EOF|ESC|  |  |  |  
2 | | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / 
3 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? 
---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
4 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O 
5 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ 
6 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o 
7 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ |  
---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
8 | € | <20> | | ƒ | „ | … | † | ‡ | ˆ | ‰ | Š | | Œ | <20> | Ž | <20> 
9 | <20> | | | “ | ” | • | | — | ˜ | ™ | š | | œ | <20> | ž | Ÿ 
A |   | ¡ | ¢ | £ | ¤ | ¥ | ¦ | § | ¨ | © | ª | « | ¬ | ­ | ® | ¯ 
B | ° | ± | ² | ³ | ´ | µ | ¶ | · | ¸ | ¹ | º | » | ¼ | ½ | ¾ | ¿ 
---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
C | À | Á |  | à | Ä | Å | Æ | Ç | È | É | Ê | Ë | Ì | Í | Î | Ï 
D | Ð | Ñ | Ò | Ó | Ô | Õ | Ö | × | Ø | Ù | Ú | Û | Ü | Ý | Þ | ß 
E | à | á | â | ã | ä | å | æ | ç | è | é | ê | ë | ì | í | î | ï 
F | ð | ñ | ò | ó | ô | õ | ö | ÷ | ø | ù | ú | û | ü | ý | þ | ÿ 
 cOLOR tEST
 ~~~~~~~~~~
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û
°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û°±²Û