[FL-1696, FL-1685] IRDA: Add RC5, decoder refactoring (#663)

* [FL-1696] IRDA: Split decoders and protocols
* IRDA: Restruct directories.
* IRDA: fix long timings
* [FL-1685] IRDA: Add RC5

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Albert Kharisov
2021-08-20 23:51:15 +03:00
committed by GitHub
parent ecff31d228
commit e6d5f4038b
24 changed files with 677 additions and 242 deletions

View File

@@ -1,11 +1,12 @@
#include <furi.h>
#include "../minunit.h"
#include "irda.h"
#include "irda_common_i.h"
#include "common/irda_common_i.h"
#include "test_data/irda_nec_test_data.srcdata"
#include "test_data/irda_necext_test_data.srcdata"
#include "test_data/irda_samsung_test_data.srcdata"
#include "test_data/irda_rc6_test_data.srcdata"
#include "test_data/irda_rc5_test_data.srcdata"
#define RUN_ENCODER(data, expected) \
run_encoder((data), COUNT_OF(data), (expected), COUNT_OF(expected))
@@ -153,16 +154,19 @@ MU_TEST(test_decoder_samsung32) {
}
MU_TEST(test_mix) {
RUN_DECODER(test_decoder_rc5_input2, test_decoder_rc5_expected2);
RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
// can use encoder data for decoding, but can't do opposite
RUN_DECODER(test_encoder_rc6_expected1, test_encoder_rc6_input1);
RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
RUN_DECODER(test_decoder_rc5_input1, test_decoder_rc5_expected1);
RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
RUN_DECODER(test_decoder_nec_input2, test_decoder_nec_expected2);
RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5);
RUN_DECODER(test_decoder_samsung32_input1, test_decoder_samsung32_expected1);
}
@@ -187,6 +191,25 @@ MU_TEST(test_decoder_necext1) {
RUN_DECODER(test_decoder_necext_input1, test_decoder_necext_expected1);
}
MU_TEST(test_decoder_rc5) {
RUN_DECODER(test_decoder_rc5x_input1, test_decoder_rc5x_expected1);
RUN_DECODER(test_decoder_rc5_input1, test_decoder_rc5_expected1);
RUN_DECODER(test_decoder_rc5_input2, test_decoder_rc5_expected2);
RUN_DECODER(test_decoder_rc5_input3, test_decoder_rc5_expected3);
RUN_DECODER(test_decoder_rc5_input4, test_decoder_rc5_expected4);
RUN_DECODER(test_decoder_rc5_input5, test_decoder_rc5_expected5);
RUN_DECODER(test_decoder_rc5_input6, test_decoder_rc5_expected6);
RUN_DECODER(test_decoder_rc5_input_all_repeats, test_decoder_rc5_expected_all_repeats);
}
MU_TEST(test_encoder_rc5x) {
RUN_ENCODER(test_decoder_rc5x_expected1, test_decoder_rc5x_input1);
}
MU_TEST(test_encoder_rc5) {
RUN_ENCODER(test_decoder_rc5_expected_all_repeats, test_decoder_rc5_input_all_repeats);
}
MU_TEST(test_decoder_rc6) {
RUN_DECODER(test_decoder_rc6_input1, test_decoder_rc6_expected1);
}
@@ -200,20 +223,24 @@ MU_TEST(test_encoder_decoder_all) {
run_encoder_decoder(test_necext_all, COUNT_OF(test_necext_all));
run_encoder_decoder(test_samsung32_all, COUNT_OF(test_samsung32_all));
run_encoder_decoder(test_rc6_all, COUNT_OF(test_rc6_all));
run_encoder_decoder(test_rc5_all, COUNT_OF(test_rc5_all));
}
MU_TEST_SUITE(test_irda_decoder_encoder) {
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
MU_RUN_TEST(test_encoder_decoder_all);
MU_RUN_TEST(test_encoder_rc5x);
MU_RUN_TEST(test_encoder_rc5);
MU_RUN_TEST(test_decoder_rc5);
MU_RUN_TEST(test_decoder_rc6);
MU_RUN_TEST(test_encoder_rc6);
MU_RUN_TEST(test_decoder_unexpected_end_in_sequence);
MU_RUN_TEST(test_decoder_nec1);
MU_RUN_TEST(test_decoder_nec2);
MU_RUN_TEST(test_decoder_samsung32);
MU_RUN_TEST(test_decoder_necext1);
MU_RUN_TEST(test_mix);
MU_RUN_TEST(test_decoder_rc6);
MU_RUN_TEST(test_encoder_rc6);
MU_RUN_TEST(test_encoder_decoder_all);
}
int run_minunit_test_irda_decoder_encoder() {

View File

@@ -0,0 +1,160 @@
/*
_______----__--____----__--____--__----____----__--__--__--__
| 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
s1 s2 t | address | command |
*/
const uint32_t test_decoder_rc5x_input1[] = {
27000 + 888, 1776, 888, 888, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888,
};
const IrdaMessage test_decoder_rc5x_expected1[] = {
{IrdaProtocolRC5X, 0x13, 0x10, false}, // toggle 0
};
/*
_______--__----____----__--____--__----____----__--__--__--__
| 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
s1 s2 t | address | command |
*/
const uint32_t test_decoder_rc5_input1[] = {
27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888,
};
const IrdaMessage test_decoder_rc5_expected1[] = {
{IrdaProtocolRC5, 0x13, 0x10, false}, // toggle 0
};
/*
_______--__--__--__----__--____--__----____----__--__--__--__
| 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
s1 s2 t | address | command |
*/
const uint32_t test_decoder_rc5_input2[] = {
27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888,
};
const IrdaMessage test_decoder_rc5_expected2[] = {
{IrdaProtocolRC5, 0x13, 0x10, false}, // toggle 1
};
/*
_______--__----____----__--____--__----____----__--__--____--
| 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
s1 s2 t | address | command |
*/
const uint32_t test_decoder_rc5_input3[] = {
27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888,
};
const IrdaMessage test_decoder_rc5_expected3[] = {
{IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 0
};
/*
_______--__--__--__----__--____--__----____----__--__--____--
| 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
s1 s2 t | address | command |
*/
const uint32_t test_decoder_rc5_input4[] = {
27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888,
};
const IrdaMessage test_decoder_rc5_expected4[] = {
{IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 1
};
/*
_______--__----____--__--__--__--__--__--__--__--__--__--__--
| 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
s1 s2 t | address | command |
*/
const uint32_t test_decoder_rc5_input5[] = {
27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888,
};
const IrdaMessage test_decoder_rc5_expected5[] = {
{IrdaProtocolRC5, 0x1F, 0x3F, false}, // toggle 0
};
/*
_______--__--__--__--__--__--__--__--__--__--__--__--__--__--
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
s1 s2 t | address | command |
*/
const uint32_t test_decoder_rc5_input6[] = {
27000 + 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888,
};
const IrdaMessage test_decoder_rc5_expected6[] = {
{IrdaProtocolRC5, 0x1F, 0x3F, false}, // toggle 1
};
const uint32_t test_decoder_rc5_input_all_repeats[] = {
27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888,
27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888,
27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888,
27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888,
27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 1776, 888,
27000 + 888, 888, 888, 888, 888, 888, 888, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888,
27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888,
27000 + 888, 888, 888, 1776, 1776, 1776, 888, 888, 1776, 888, 888, 1776, 1776, 1776, 888, 888, 888, 888, 888, 888,
27000 + 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888,
27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888,
27000 + 888, 888, 888, 1776, 1776, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, 888,
};
const IrdaMessage test_decoder_rc5_expected_all_repeats[] = {
{IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 0
{IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 1
{IrdaProtocolRC5, 0x13, 0x11, true}, // toggle 1
{IrdaProtocolRC5, 0x13, 0x11, true}, // toggle 1
{IrdaProtocolRC5, 0x13, 0x11, false}, // toggle 0
{IrdaProtocolRC5, 0x13, 0x10, false}, // toggle 1
{IrdaProtocolRC5, 0x13, 0x10, false}, // toggle 0
{IrdaProtocolRC5, 0x13, 0x10, true}, // toggle 0
{IrdaProtocolRC5, 0x1F, 0x3F, false}, // toggle 1
{IrdaProtocolRC5, 0x1F, 0x3F, false}, // toggle 0
{IrdaProtocolRC5, 0x1F, 0x3F, true}, // toggle 0
};
const IrdaMessage test_rc5_all[] = {
{IrdaProtocolRC5, 0x1F, 0x3F, false},
{IrdaProtocolRC5, 0x00, 0x00, false},
{IrdaProtocolRC5, 0x10, 0x01, false},
{IrdaProtocolRC5, 0x01, 0x20, false},
{IrdaProtocolRC5, 0x01, 0x20, false},
{IrdaProtocolRC5, 0x01, 0x20, true},
{IrdaProtocolRC5, 0x01, 0x20, true},
{IrdaProtocolRC5, 0x01, 0x20, true},
{IrdaProtocolRC5, 0x01, 0x20, true},
{IrdaProtocolRC5, 0x1F, 0x3F, false},
{IrdaProtocolRC5, 0x0A, 0x2A, false},
{IrdaProtocolRC5, 0x15, 0x15, false},
{IrdaProtocolRC5, 0x15, 0x15, true},
{IrdaProtocolRC5X, 0x1F, 0x3F, false},
{IrdaProtocolRC5X, 0x00, 0x00, false},
{IrdaProtocolRC5X, 0x10, 0x01, false},
{IrdaProtocolRC5X, 0x01, 0x20, false},
{IrdaProtocolRC5X, 0x01, 0x20, false},
{IrdaProtocolRC5X, 0x01, 0x20, true},
{IrdaProtocolRC5X, 0x01, 0x20, true},
{IrdaProtocolRC5X, 0x01, 0x20, true},
{IrdaProtocolRC5X, 0x01, 0x20, true},
{IrdaProtocolRC5X, 0x1F, 0x3F, false},
{IrdaProtocolRC5X, 0x0A, 0x2A, false},
{IrdaProtocolRC5X, 0x15, 0x15, false},
{IrdaProtocolRC5X, 0x15, 0x15, true},
};

View File

@@ -15,17 +15,17 @@ _____---------______--____--__--__------____--____--__----____--__----__--__--__
*/
const uint32_t test_decoder_rc6_input1[] = {
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444 + 888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 444 + 444, 888 + 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 888, // failed
};
const IrdaMessage test_decoder_rc6_expected1[] = {
@@ -54,14 +54,14 @@ const IrdaMessage test_encoder_rc6_input1[] = {
};
const uint32_t test_encoder_rc6_expected1[] = {
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
2700, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 888,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444, 888, 888+444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
27000, 2666, 889, 444, 888, 444, 444, 444, 444, 444+888, 888, 444, 888, 444, 444, 888, 888, 444, 444, 888, 444, 444, 444, 444, 888, 888, 888, 444, 444, 444, 444, 444, 444, 444, 444, 444,
};