optimise simulation handling

Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2025-09-30 20:16:10 +02:00
parent 08b0e04584
commit 99aa30c8e5
13 changed files with 482 additions and 133 deletions

View File

@@ -1,4 +1,5 @@
idf_component_register(SRCS
src/color.c
src/led_status.c
src/led_strip_ws2812.c
INCLUDE_DIRS "include"

View File

@@ -9,4 +9,14 @@ typedef struct
uint8_t blue;
} rgb_t;
void interpolate_color(const rgb_t start_color, const rgb_t end_color, float fraction, rgb_t *out_color);
typedef struct
{
uint8_t h;
uint8_t s;
uint8_t v;
} hsv_t;
rgb_t interpolate_color_rgb(rgb_t start, rgb_t end, float factor);
rgb_t interpolate_color_hsv(rgb_t start, rgb_t end, float factor);
hsv_t rgb_to_hsv(rgb_t rgb);
rgb_t hsv_to_rgb(hsv_t hsv);

View File

@@ -1,8 +1,183 @@
#include "color.h"
#include <math.h>
void interpolate_color(const rgb_t start_color, const rgb_t end_color, float fraction, rgb_t *out_color)
rgb_t interpolate_color_rgb(rgb_t start, rgb_t end, float factor)
{
out_color->r = start_color.r + (end_color.r - start_color.r) * fraction;
out_color->g = start_color.g + (end_color.g - start_color.g) * fraction;
out_color->b = start_color.b + (end_color.b - start_color.b) * fraction;
}
// Clamp factor to [0, 1]
if (factor > 1.0f)
factor = 1.0f;
if (factor < 0.0f)
factor = 0.0f;
rgb_t result;
result.red = (uint8_t)(start.red + (end.red - start.red) * factor);
result.green = (uint8_t)(start.green + (end.green - start.green) * factor);
result.blue = (uint8_t)(start.blue + (end.blue - start.blue) * factor);
return result;
}
rgb_t interpolate_color_hsv(rgb_t start, rgb_t end, float factor)
{
// Clamp factor to [0, 1]
if (factor > 1.0f)
factor = 1.0f;
if (factor < 0.0f)
factor = 0.0f;
// Convert RGB to HSV
hsv_t start_hsv = rgb_to_hsv(start);
hsv_t end_hsv = rgb_to_hsv(end);
// Handle hue interpolation carefully (circular)
double h1 = start_hsv.h;
double h2 = end_hsv.h;
double diff = h2 - h1;
if (diff > 180.0)
{
h1 += 360.0;
}
else if (diff < -180.0)
{
h2 += 360.0;
}
// Interpolate HSV values
hsv_t interpolated_hsv;
interpolated_hsv.h = fmod(h1 + (h2 - h1) * factor, 360.0);
if (interpolated_hsv.h < 0)
{
interpolated_hsv.h += 360.0;
}
interpolated_hsv.s = start_hsv.s + (end_hsv.s - start_hsv.s) * factor;
interpolated_hsv.v = start_hsv.v + (end_hsv.v - start_hsv.v) * factor;
// Convert back to RGB
return hsv_to_rgb(interpolated_hsv);
}
hsv_t rgb_to_hsv(rgb_t rgb)
{
hsv_t hsv;
uint8_t max = rgb.red;
uint8_t min = rgb.red;
if (rgb.green > max)
max = rgb.green;
if (rgb.blue > max)
max = rgb.blue;
if (rgb.green < min)
min = rgb.green;
if (rgb.blue < min)
min = rgb.blue;
uint8_t delta = max - min;
// Value berechnen
hsv.v = max;
// Saturation berechnen
if (max != 0)
{
hsv.s = (delta * 255) / max;
}
else
{
// Schwarz (r = g = b = 0)
hsv.s = 0;
hsv.h = 0;
return hsv;
}
// Hue berechnen
if (delta != 0)
{
int16_t hue;
if (rgb.red == max)
{
// Zwischen Gelb und Magenta
hue = ((int16_t)(rgb.green - rgb.blue) * 30) / delta;
if (hue < 0)
hue += 180;
}
else if (rgb.green == max)
{
// Zwischen Cyan und Gelb
hue = 60 + ((int16_t)(rgb.blue - rgb.red) * 30) / delta;
}
else
{
// Zwischen Magenta und Cyan
hue = 120 + ((int16_t)(rgb.red - rgb.green) * 30) / delta;
}
hsv.h = (uint8_t)hue;
}
else
{
// Graustufe
hsv.h = 0;
}
return hsv;
}
rgb_t hsv_to_rgb(hsv_t hsv)
{
rgb_t rgb;
if (hsv.s == 0)
{
// Graustufe
rgb.red = hsv.v;
rgb.green = hsv.v;
rgb.blue = hsv.v;
}
else
{
uint16_t region = hsv.h / 30;
uint16_t remainder = (hsv.h - (region * 30)) * 6;
uint8_t p = (hsv.v * (255 - hsv.s)) / 255;
uint8_t q = (hsv.v * (255 - ((hsv.s * remainder) / 180))) / 255;
uint8_t t = (hsv.v * (255 - ((hsv.s * (180 - remainder)) / 180))) / 255;
switch (region)
{
case 0:
rgb.red = hsv.v;
rgb.green = t;
rgb.blue = p;
break;
case 1:
rgb.red = q;
rgb.green = hsv.v;
rgb.blue = p;
break;
case 2:
rgb.red = p;
rgb.green = hsv.v;
rgb.blue = t;
break;
case 3:
rgb.red = p;
rgb.green = q;
rgb.blue = hsv.v;
break;
case 4:
rgb.red = t;
rgb.green = p;
rgb.blue = hsv.v;
break;
default: // case 5:
rgb.red = hsv.v;
rgb.green = p;
rgb.blue = q;
break;
}
}
return rgb;
}

View File

@@ -12,7 +12,8 @@ typedef struct
__BEGIN_DECLS
char *get_time(void);
esp_err_t add_light_item(const char time[5], uint8_t red, uint8_t green, uint8_t blue);
esp_err_t add_light_item(const char time[5], uint8_t red, uint8_t green, uint8_t blue, uint8_t white,
uint8_t brightness, uint8_t saturation);
void cleanup_light_items(void);
void start_simulate_day(void);
void start_simulate_night(void);

View File

@@ -7,6 +7,7 @@
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -37,12 +38,36 @@ typedef struct light_item_node_t
static light_item_node_t *head = NULL;
static light_item_node_t *tail = NULL;
// Interpolation mode selection
typedef enum
{
INTERPOLATION_RGB,
INTERPOLATION_HSV
} interpolation_mode_t;
// You can change this to test different interpolation methods
static const interpolation_mode_t interpolation_mode = INTERPOLATION_RGB;
char *get_time(void)
{
return time;
}
esp_err_t add_light_item(const char time[5], uint8_t red, uint8_t green, uint8_t blue)
// Main interpolation function that selects the appropriate method
static rgb_t interpolate_color(rgb_t start, rgb_t end, float factor)
{
switch (interpolation_mode)
{
case INTERPOLATION_RGB:
return interpolate_color_rgb(start, end, factor);
case INTERPOLATION_HSV:
default:
return interpolate_color_hsv(start, end, factor);
}
}
esp_err_t add_light_item(const char time[5], uint8_t red, uint8_t green, uint8_t blue, uint8_t white,
uint8_t brightness, uint8_t saturation)
{
// Allocate memory for a new node in PSRAM.
light_item_node_t *new_node = (light_item_node_t *)heap_caps_malloc(sizeof(light_item_node_t), MALLOC_CAP_SPIRAM);
@@ -52,11 +77,17 @@ esp_err_t add_light_item(const char time[5], uint8_t red, uint8_t green, uint8_t
return ESP_FAIL;
}
rgb_t color = {.red = red, .green = green, .blue = blue};
hsv_t hsv = rgb_to_hsv(color);
hsv.v = brightness;
hsv.s = saturation;
rgb_t adjusted_color = hsv_to_rgb(hsv);
// Initialize the data of the new node.
memcpy(new_node->time, time, sizeof(new_node->time));
new_node->red = red;
new_node->green = green;
new_node->blue = blue;
new_node->red = adjusted_color.red;
new_node->green = adjusted_color.green;
new_node->blue = adjusted_color.blue;
new_node->next = NULL;
// Append the new node to the end of the list.
@@ -131,16 +162,62 @@ static light_item_node_t *find_best_light_item_for_time(int hhmm)
if (best_item == NULL)
{
ESP_LOGW(TAG, "No suitable light item found for time up to %04d", hhmm);
}
else
{
ESP_LOGD(TAG, "Best light item for time %04d is %s", hhmm, best_item->time);
// If no item is found for the given time (e.g., before the first item of the day),
// find the last item of the previous day.
best_time = -1;
current = head;
while (current != NULL)
{
int current_time = atoi(current->time);
if (current_time > best_time)
{
best_time = current_time;
best_item = current;
}
current = current->next;
}
}
return best_item;
}
static light_item_node_t *find_next_light_item_for_time(int hhmm)
{
light_item_node_t *current = head;
light_item_node_t *next_item = NULL;
int next_time = 9999; // Initialize with a value larger than any possible time
// First pass: find the soonest time after hhmm
while (current != NULL)
{
int current_time = atoi(current->time);
if (current_time > hhmm && current_time < next_time)
{
next_time = current_time;
next_item = current;
}
current = current->next;
}
// If no item is found for the rest of the day, wrap around to the beginning of the next day
if (next_item == NULL)
{
current = head;
next_time = 9999;
while (current != NULL)
{
int current_time = atoi(current->time);
if (current_time < next_time)
{
next_time = current_time;
next_item = current;
}
current = current->next;
}
}
return next_item;
}
void start_simulate_day(void)
{
initialize_light_items();
@@ -186,7 +263,6 @@ void simulate_cycle(void *args)
cycle_duration_minutes, delay_ms);
int current_minute_of_day = 0;
light_item_node_t *last_item = NULL;
while (1)
{
@@ -196,15 +272,47 @@ void simulate_cycle(void *args)
time = time_to_string(hhmm);
light_item_node_t *current_item = find_best_light_item_for_time(hhmm);
light_item_node_t *next_item = find_next_light_item_for_time(hhmm);
if (current_item != NULL && current_item != last_item)
if (current_item != NULL && next_item != NULL)
{
ESP_LOGI(TAG, "Simulating time: %02d:%02d -> Closest schedule is %s. R:%d, G:%d, B:%d", hours, minutes,
current_item->time, current_item->red, current_item->green, current_item->blue);
int current_item_time_min = (atoi(current_item->time) / 100) * 60 + (atoi(current_item->time) % 100);
int next_item_time_min = (atoi(next_item->time) / 100) * 60 + (atoi(next_item->time) % 100);
if (next_item_time_min < current_item_time_min)
{
next_item_time_min += total_minutes_in_day;
}
int minutes_since_current_item_start = current_minute_of_day - current_item_time_min;
if (minutes_since_current_item_start < 0)
{
minutes_since_current_item_start += total_minutes_in_day;
}
int interval_duration = next_item_time_min - current_item_time_min;
if (interval_duration == 0)
{
interval_duration = 1;
}
float interpolation_factor = (float)minutes_since_current_item_start / (float)interval_duration;
// Prepare colors for interpolation
rgb_t start_rgb = {.red = current_item->red, .green = current_item->green, .blue = current_item->blue};
rgb_t end_rgb = {.red = next_item->red, .green = next_item->green, .blue = next_item->blue};
// Use the interpolation function
rgb_t final_rgb = interpolate_color(start_rgb, end_rgb, interpolation_factor);
led_strip_update(LED_STATE_SIMULATION, final_rgb);
}
else if (current_item != NULL)
{
// No next item, just use current
led_strip_update(
LED_STATE_SIMULATION,
(rgb_t){.red = current_item->red, .green = current_item->green, .blue = current_item->blue});
last_item = current_item;
}
vTaskDelay(pdMS_TO_TICKS(delay_ms));

View File

@@ -11,10 +11,10 @@ static const char *TAG = "storage";
void initialize_storage()
{
esp_vfs_spiffs_conf_t conf = {
.base_path = "/spiffs", // Der Basispfad, unter dem das Dateisystem gemountet wird
.partition_label = NULL, // NULL, um die erste gefundene SPIFFS-Partition zu verwenden
.max_files = 5, // Maximale Anzahl gleichzeitig geöffneter Dateien
.format_if_mount_failed = false // Partition formatieren, wenn das Mounten fehlschlägt
.base_path = "/spiffs",
.partition_label = NULL,
.max_files = 5,
.format_if_mount_failed = false,
};
esp_err_t ret = esp_vfs_spiffs_register(&conf);
@@ -33,7 +33,7 @@ void initialize_storage()
{
ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
}
return; // Oder entsprechende Fehlerbehandlung
return;
}
}
@@ -47,24 +47,30 @@ void load_file(const char *filename)
return;
}
char line[128]; // Puffer für eine Zeile, vergrößert für mehr Sicherheit
char line[128];
uint8_t line_number = 0;
while (fgets(line, sizeof(line), f))
{
// Entferne möglichen Zeilenumbruch am Ende
char *pos = strchr(line, '\n');
if (pos)
{
*pos = '\0';
}
char time[5] = {0}; // 4 Zeichen + Nullterminator
int red, green, blue;
char time[10] = {0};
int red, green, blue, white, brightness, saturation;
// Parse die Zeile im Format "HHMM,R,G,B"
int items_scanned = sscanf(line, "%4[^,],%d,%d,%d", time, &red, &green, &blue);
if (items_scanned == 4)
int items_scanned = sscanf(line, "%d,%d,%d,%d,%d,%d", &red, &green, &blue, &white, &brightness, &saturation);
if (items_scanned == 6)
{
add_light_item(time, (uint8_t)red, (uint8_t)green, (uint8_t)blue);
int total_minutes = line_number * 30;
int hours = total_minutes / 60;
int minutes = total_minutes % 60;
snprintf(time, sizeof(time), "%02d%02d", hours, minutes);
add_light_item(time, red, green, blue, white, brightness, saturation);
line_number++;
}
else
{
@@ -74,4 +80,4 @@ void load_file(const char *filename)
fclose(f);
ESP_LOGI(TAG, "Finished loading file.");
}
}

View File

@@ -21,4 +21,4 @@ idf_component_register(SRCS
rmaker_common
)
spiffs_create_partition_image(storage ../spiffs_image FLASH_IN_PROJECT)
spiffs_create_partition_image(storage ../storage FLASH_IN_PROJECT)

View File

@@ -1,48 +0,0 @@
0000,25,25,112
0030,25,25,112
0100,25,25,112
0130,25,25,112
0200,25,25,112
0230,25,25,112
0300,25,25,112
0330,25,25,112
0400,25,25,112
0430,140,25,112
0500,255,130,112
0530,255,155,112
0600,255,177,115
0630,255,200,135
0700,255,219,170
0730,255,234,205
0800,255,249,240
0830,255,249,250
0900,239,245,255
0930,224,240,255
1000,215,235,255
1030,212,234,255
1100,210,233,255
1130,208,232,255
1200,207,231,255
1230,205,230,255
1300,204,229,255
1330,204,229,255
1400,206,230,255
1430,208,231,255
1500,213,232,255
1530,219,234,255
1600,229,239,255
1630,236,246,255
1700,255,252,251
1730,255,243,236
1800,255,225,202
1830,255,203,174
1900,255,178,129
1930,255,146,85
2000,255,93,38
2030,140,55,70
2100,25,25,112
2130,25,25,112
2200,25,25,112
2230,25,25,112
2300,25,25,112
2330,25,25,112
1 0000 25 25 112
2 0030 25 25 112
3 0100 25 25 112
4 0130 25 25 112
5 0200 25 25 112
6 0230 25 25 112
7 0300 25 25 112
8 0330 25 25 112
9 0400 25 25 112
10 0430 140 25 112
11 0500 255 130 112
12 0530 255 155 112
13 0600 255 177 115
14 0630 255 200 135
15 0700 255 219 170
16 0730 255 234 205
17 0800 255 249 240
18 0830 255 249 250
19 0900 239 245 255
20 0930 224 240 255
21 1000 215 235 255
22 1030 212 234 255
23 1100 210 233 255
24 1130 208 232 255
25 1200 207 231 255
26 1230 205 230 255
27 1300 204 229 255
28 1330 204 229 255
29 1400 206 230 255
30 1430 208 231 255
31 1500 213 232 255
32 1530 219 234 255
33 1600 229 239 255
34 1630 236 246 255
35 1700 255 252 251
36 1730 255 243 236
37 1800 255 225 202
38 1830 255 203 174
39 1900 255 178 129
40 1930 255 146 85
41 2000 255 93 38
42 2030 140 55 70
43 2100 25 25 112
44 2130 25 25 112
45 2200 25 25 112
46 2230 25 25 112
47 2300 25 25 112
48 2330 25 25 112

View File

@@ -1,48 +0,0 @@
0000,25,25,112
0030,25,25,112
0100,25,25,112
0130,25,25,112
0200,25,25,112
0230,25,25,112
0300,25,25,112
0330,62,25,95
0400,102,60,78
0430,140,78,61
0500,178,95,44
0530,214,113,27
0600,255,130,10
0630,255,139,22
0700,255,147,34
0730,255,155,46
0800,255,163,58
0830,255,172,70
0900,255,180,82
0930,255,189,93
1000,255,197,105
1030,255,205,117
1100,255,213,129
1130,255,222,141
1200,255,230,153
1230,255,222,143
1300,255,214,133
1330,255,206,124
1400,255,198,114
1430,255,191,104
1500,255,183,94
1530,255,175,84
1600,255,167,74
1630,255,159,64
1700,255,151,55
1730,255,143,45
1800,255,135,35
1830,214,116,45
1900,178,98,61
1930,140,80,74
2000,102,62,86
2030,63,44,99
2100,25,25,112
2130,25,25,112
2200,25,25,112
2230,25,25,112
2300,25,25,112
2330,25,25,112
1 0000 25 25 112
2 0030 25 25 112
3 0100 25 25 112
4 0130 25 25 112
5 0200 25 25 112
6 0230 25 25 112
7 0300 25 25 112
8 0330 62 25 95
9 0400 102 60 78
10 0430 140 78 61
11 0500 178 95 44
12 0530 214 113 27
13 0600 255 130 10
14 0630 255 139 22
15 0700 255 147 34
16 0730 255 155 46
17 0800 255 163 58
18 0830 255 172 70
19 0900 255 180 82
20 0930 255 189 93
21 1000 255 197 105
22 1030 255 205 117
23 1100 255 213 129
24 1130 255 222 141
25 1200 255 230 153
26 1230 255 222 143
27 1300 255 214 133
28 1330 255 206 124
29 1400 255 198 114
30 1430 255 191 104
31 1500 255 183 94
32 1530 255 175 84
33 1600 255 167 74
34 1630 255 159 64
35 1700 255 151 55
36 1730 255 143 45
37 1800 255 135 35
38 1830 214 116 45
39 1900 178 98 61
40 1930 140 80 74
41 2000 102 62 86
42 2030 63 44 99
43 2100 25 25 112
44 2130 25 25 112
45 2200 25 25 112
46 2230 25 25 112
47 2300 25 25 112
48 2330 25 25 112

View File

@@ -0,0 +1,48 @@
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
140,25,112,0,100,250
255,130,112,0,130,250
255,155,112,0,150,250
255,177,115,0,170,250
255,200,135,0,190,250
255,219,170,0,210,250
255,234,205,0,217,250
255,249,240,0,223,250
255,249,250,0,227,250
239,245,255,0,234,250
224,240,255,0,239,250
215,235,255,0,244,250
212,234,255,0,248,250
210,233,255,0,250,250
208,232,255,0,252,250
207,231,255,0,255,250
205,230,255,0,252,250
204,229,255,0,250,250
204,229,255,0,247,250
206,230,255,0,245,250
208,231,255,0,243,250
213,232,255,0,240,250
219,234,255,0,237,250
229,239,255,0,235,250
236,246,255,0,233,250
255,252,251,0,230,250
255,243,236,0,225,250
255,225,202,0,220,250
255,203,174,0,205,250
255,178,129,0,190,250
255,146,85,0,165,250
255,93,38,0,140,250
140,55,70,0,120,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
1 25 25 112 0 100 250
2 25 25 112 0 100 250
3 25 25 112 0 100 250
4 25 25 112 0 100 250
5 25 25 112 0 100 250
6 25 25 112 0 100 250
7 25 25 112 0 100 250
8 25 25 112 0 100 250
9 25 25 112 0 100 250
10 140 25 112 0 100 250
11 255 130 112 0 130 250
12 255 155 112 0 150 250
13 255 177 115 0 170 250
14 255 200 135 0 190 250
15 255 219 170 0 210 250
16 255 234 205 0 217 250
17 255 249 240 0 223 250
18 255 249 250 0 227 250
19 239 245 255 0 234 250
20 224 240 255 0 239 250
21 215 235 255 0 244 250
22 212 234 255 0 248 250
23 210 233 255 0 250 250
24 208 232 255 0 252 250
25 207 231 255 0 255 250
26 205 230 255 0 252 250
27 204 229 255 0 250 250
28 204 229 255 0 247 250
29 206 230 255 0 245 250
30 208 231 255 0 243 250
31 213 232 255 0 240 250
32 219 234 255 0 237 250
33 229 239 255 0 235 250
34 236 246 255 0 233 250
35 255 252 251 0 230 250
36 255 243 236 0 225 250
37 255 225 202 0 220 250
38 255 203 174 0 205 250
39 255 178 129 0 190 250
40 255 146 85 0 165 250
41 255 93 38 0 140 250
42 140 55 70 0 120 250
43 25 25 112 0 100 250
44 25 25 112 0 100 250
45 25 25 112 0 100 250
46 25 25 112 0 100 250
47 25 25 112 0 100 250
48 25 25 112 0 100 250

View File

@@ -0,0 +1,48 @@
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
62,25,95,0,100,250
102,60,78,0,100,250
140,78,61,0,115,250
178,95,44,0,130,250
214,113,27,0,150,250
255,130,10,0,170,250
255,139,22,0,190,250
255,147,34,0,210,250
255,155,46,0,215,250
255,163,58,0,220,250
255,172,70,0,225,250
255,180,82,0,230,250
255,189,93,0,235,250
255,197,105,0,240,250
255,205,117,0,245,250
255,213,129,0,250,250
255,222,141,0,252,250
255,230,153,0,255,250
255,222,143,0,252,250
255,214,133,0,250,250
255,206,124,0,247,250
255,198,114,0,245,250
255,191,104,0,242,250
255,183,94,0,240,250
255,175,84,0,237,250
255,167,74,0,235,250
255,159,64,0,233,250
255,151,55,0,230,250
255,143,45,0,225,250
255,135,35,0,220,250
214,116,45,0,205,250
178,98,61,0,190,250
140,80,74,0,165,250
102,62,86,0,140,250
63,44,99,0,120,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
25,25,112,0,100,250
1 25 25 112 0 100 250
2 25 25 112 0 100 250
3 25 25 112 0 100 250
4 25 25 112 0 100 250
5 25 25 112 0 100 250
6 25 25 112 0 100 250
7 25 25 112 0 100 250
8 62 25 95 0 100 250
9 102 60 78 0 100 250
10 140 78 61 0 115 250
11 178 95 44 0 130 250
12 214 113 27 0 150 250
13 255 130 10 0 170 250
14 255 139 22 0 190 250
15 255 147 34 0 210 250
16 255 155 46 0 215 250
17 255 163 58 0 220 250
18 255 172 70 0 225 250
19 255 180 82 0 230 250
20 255 189 93 0 235 250
21 255 197 105 0 240 250
22 255 205 117 0 245 250
23 255 213 129 0 250 250
24 255 222 141 0 252 250
25 255 230 153 0 255 250
26 255 222 143 0 252 250
27 255 214 133 0 250 250
28 255 206 124 0 247 250
29 255 198 114 0 245 250
30 255 191 104 0 242 250
31 255 183 94 0 240 250
32 255 175 84 0 237 250
33 255 167 74 0 235 250
34 255 159 64 0 233 250
35 255 151 55 0 230 250
36 255 143 45 0 225 250
37 255 135 35 0 220 250
38 214 116 45 0 205 250
39 178 98 61 0 190 250
40 140 80 74 0 165 250
41 102 62 86 0 140 250
42 63 44 99 0 120 250
43 25 25 112 0 100 250
44 25 25 112 0 100 250
45 25 25 112 0 100 250
46 25 25 112 0 100 250
47 25 25 112 0 100 250
48 25 25 112 0 100 250

View File

@@ -0,0 +1,48 @@
25,24,112,0,100,250
25,23,106,0,100,250
25,22,100,0,100,250
25,21,95,0,100,250
25,19,89,0,100,250
25,18,84,0,100,250
25,17,78,0,100,250
62,19,72,0,100,250
102,51,67,0,100,250
140,61,48,0,115,250
178,55,25,0,130,250
214,50,12,0,150,250
255,44,3,0,170,250
255,46,7,0,190,250
255,48,11,0,210,250
255,50,15,0,215,250
255,52,18,0,220,250
255,54,22,0,225,250
255,56,25,0,230,250
255,58,28,0,235,250
255,60,32,0,240,250
255,62,35,0,245,250
255,64,38,0,250,250
255,65,41,0,252,250
255,67,45,0,255,250
255,69,44,0,252,250
255,71,44,0,250,250
255,73,44,0,247,250
255,75,43,0,245,250
255,77,42,0,242,250
255,79,40,0,240,250
255,81,39,0,237,250
255,83,36,0,235,250
255,85,34,0,233,250
255,87,31,0,230,250
255,88,27,0,225,250
255,90,23,0,220,250
214,92,36,0,205,250
178,94,58,0,190,250
140,96,89,0,165,250
102,71,98,0,140,250
63,44,100,0,120,250
25,22,102,0,100,250
25,23,104,0,100,250
25,23,106,0,100,250
25,24,108,0,100,250
25,24,110,0,100,250
25,24,112,0,100,250
1 25 24 112 0 100 250
2 25 23 106 0 100 250
3 25 22 100 0 100 250
4 25 21 95 0 100 250
5 25 19 89 0 100 250
6 25 18 84 0 100 250
7 25 17 78 0 100 250
8 62 19 72 0 100 250
9 102 51 67 0 100 250
10 140 61 48 0 115 250
11 178 55 25 0 130 250
12 214 50 12 0 150 250
13 255 44 3 0 170 250
14 255 46 7 0 190 250
15 255 48 11 0 210 250
16 255 50 15 0 215 250
17 255 52 18 0 220 250
18 255 54 22 0 225 250
19 255 56 25 0 230 250
20 255 58 28 0 235 250
21 255 60 32 0 240 250
22 255 62 35 0 245 250
23 255 64 38 0 250 250
24 255 65 41 0 252 250
25 255 67 45 0 255 250
26 255 69 44 0 252 250
27 255 71 44 0 250 250
28 255 73 44 0 247 250
29 255 75 43 0 245 250
30 255 77 42 0 242 250
31 255 79 40 0 240 250
32 255 81 39 0 237 250
33 255 83 36 0 235 250
34 255 85 34 0 233 250
35 255 87 31 0 230 250
36 255 88 27 0 225 250
37 255 90 23 0 220 250
38 214 92 36 0 205 250
39 178 94 58 0 190 250
40 140 96 89 0 165 250
41 102 71 98 0 140 250
42 63 44 100 0 120 250
43 25 22 102 0 100 250
44 25 23 104 0 100 250
45 25 23 106 0 100 250
46 25 24 108 0 100 250
47 25 24 110 0 100 250
48 25 24 112 0 100 250

View File

@@ -1 +1 @@
0.1.0
0.1.1