Kajoj Home Page
Menu
Packages (slackware)
ekg

Misc

noooxml

Dzisiaj uporamy się z problemem wymiany dysków w software'owej macierzy RAID1. Sytuacja przedstawia się tak, iż nowe dyski są decydowanie większe od tych, które aktualnie pracują w raidzie. Co więcej chcemy wykonać wszystko on-line, tj. bez wyłączania serwera. Jeżeli w twoim przypadku podłączanie dysków hot-swap nie działa ok, będziesz musiał wyłączyć serwer co najmniej dwa razy w celu podmiany dysków. Jeszcze jedna bardzo ważna sprawa: system plików którego używam to ReiserFS... system ten pozwala na rozszerzanie partycji online. W przypadku ext2/3 problem jest nieco trudniejszy, i nie będzie ujęty w tym artykule.

Ok zaczynamy. Sytuacja z dyskami przedstawia się następująca: raid /dev/md0 tworzą dyski /dev/sda2 oraz /dev/sdb2, raid /dev/md1 dyski /dev/sda3 oraz /dev/sdb3. Partycje /dev/sda1 oraz /dev/sdb1 nie są zraidowane i służą jako swap. Na początek podmieniamy dysk /dev/sdb na nowy większy.

Odłączam dysk /dev/sdb od systemu:

# swapoff /dev/sdb1
# mdadm --manage /dev/md0 --fail /dev/sdb2
# mdadm --manage /dev/md1 --fail /dev/sdb3
# mdadm --manage /dev/md0 --remove /dev/sdb2
# mdadm --manage /dev/md1 --remove /dev/sdb3

Teraz odłączam dysk przez hotswap lub wyłączam serwer i podmieniam dysk na większy. Po ponownym uruchomieniu serwera lub podłączeniu nowego dysku należy dodać go do RAIDa. Najpierw jednak należy go podzielić na partycje.

# cfdisk /dev/sdb
  1. dodaję partycję swap /dev/sdb1
  2. dodaję bootowalną partcję /dev/sdb2 (analogicznie tak jak to mam na dysku /dev/sda) typu Linux raid autodetect co najmniej tej wielkości co partycja /dev/sda2, ja powiększyłem moją z 80GB na 250GB.
  3. dodaję partcję /dev/sdb3 typu Linux raid autodetect
  4. zapisuję tablicę partycji i wychodzę z programu.

Teraz podłączę nowy dysk do systemu:

# mkswap /dev/sdb1
# swapon /dev/sdb1
# mdadm --manage /dev/md0 --add /dev/sdb2
# mdadm --manage /dev/md1 --add /dev/sdb3

Teram chwila przerwy, gdyż musimy poczekać raid się zsynchronizuje. Więc kawka, snikers, papieros, piwo czy playstation mile widziane. Możemy obserwować postęp synchronizacji przez wydanie polecenia watch -n 1 'cat /proc/mdstat'

Jak synchronizacja się skończy odłączamy pozostałe dyski RAIDa. Aha. Jeżeli używasz lilo wydaj polecenie aktualizacji wpisów mbr (gdyż nowy dysk takiego wpisu nie posiada).

# swapoff /dev/sda1
# mdadm --manage /dev/md0 --fail /dev/sda2
# mdadm --manage /dev/md1 --fail /dev/sda3
# mdadm --manage /dev/md0 --remove /dev/sda2
# mdadm --manage /dev/md1 --remove /dev/sda3

Jeżeli posiadasz więcej redundentnych dysków wykonaj powyższy krok dla każdego z nich. Analogicznie jak za pierwszym razem odłączam i podmieniam dysk na nowy. Partycjonuje go dokładnie tak samo jak nowy dysk /dev/sdb, i przyłączam do systemu (jak? patrz wyżej).

OK. Teraz należy rozszerzyć tablicę macierzy.

# mdadm --grow /dev/md0 --size=max
# mdadm --grow /dev/md1 --size=max

Po tej operacje urządzenia blokowe /dev/md0 i /dev/md1 powinny mieć rozmiar najmniejszego dysku wchodzącego w ich skład. Teraz należy poinformować system plików, aby korzystał z całej tej przestrzeni. Dla systemu ReiserFS można to zrobić on-line prostym pleceniem:

# resize_reiserfs /dev/md0
# resize_reiserfs /dev/md1

Każde z nich będzie się chwilkę wykonywać bez żądnej informacji dla użytkownika... ale bez stresu... nic się nie zawiesiło, po prostu chwilkę to trwa.

Na koniec użytkownicy lilo wydają poleceni lilo aby odświeżyć rekordy mbr na każdym z nadmiarowych dysków. I to tyle. jeszcze warto poczekać aż cała macierz "dojdzie do siebie" obserwując /proc/mdstat przy pomocy watch -n 1 'cat /proc/mdstat'

No i to tyle... można cieszyć się dużym dyskiem df -h



Dodano: 2009-12-21 16:40:47 | komentarze (0)

Jakiś czas temu mą uwagę przykuła reklama zupek Amino, bynajmniej nie z powodu ich pysznego smaku, czy oryginalnego podejścia do rekomendacji zupopodobnego produktu firmy Amino. Zaciekawił mnie konkurs... konkurs na pierwszy rzut oka banalny... wystarczy pozbierać kupony i wymienić docelowa kwotę na gotówkę. Niby nic trudnego... ale kwotę którą można wypłacić to wielokrotność tysiąca złotych, nie większa niż 10000. Niby wszystko fajnie, jednak kwoty, które występują w zupkach wcale nie są takie "okrągłe'. Zakładamy, że może być to dowolna liczbą mniejsza niż 10k, czyli jest ich właśnie niespełna 10k. Teraz jeżeli uzbieramy około 10 kuponów, to na pierwszy rzut oka można stwierdzić, czy się wygrało, czy też nie. Gorzej jak jest się zapalonym pożeraczem produktów zakładów chemicznych Amino i ma się tych kuponów więcej. Pojawia się problem: jak mam znaleźć okrągłą kwotę z N kuponów, skoro liczba kombinacji to 2^N. Dla przykładu 56 kuponów to 72057594037927936 kombinacji ;)

Otóż problem z którym się tu spotykamy jest jednym z ważniejszych problemów teorii złożoności i fachowo nazywa się problemem sumy podzbioru. Co gorsza problem ten jest problemem klasy NPC, czyli niedeterministycznie wielomianowy, czyli taki dla którego nie ma rozwiązania dokładnego w czasie wielomianowym. Innymi słowy liczenie na kartce od razy możemy sobie odpuścić.

Ok. w takim razie zaprzęgnijmy do tego komputer. Ale to rodzi kolejny problem: jak w rozsądnym czasie wygenerować wszystkie kombinacje kuponów, spamiętać je i jeszcze zmieścić się w możliwie małej pamięci.

Może po kolei. Zastanówmy się najpierw jak będziemy przechowywać listy kuponów tworzących dane sumy. Samo pytanie wskazuje na użycie listy. Ale nie ma sensu dla każdej sumy tworzyć oddzielnej listy, tylko wystarczy nam taki zabieg: załóżmy, że mamy dwie sumy 16 i 26. 16 składa się z 1,3,4,8; natomiast 26 z tych samych kuponów co 16 oraz kuponu 10, czyli 1,3,4,8,10.
Gdybyśmy zapisywali oddzielnie w tablicy kupony potrzebne do złożenia 16 i 26 potrzebowalibyśmy 9 komórek takiej tablicy:
16 = 1 + 3 + 4 + 8
26 = 1 + 3 + 4 + 8 + 10
Jeżeli natomiast użyjemy listy w sposób następujący:

zużyjemy tylko 5 komórek. I tak też zrobimy.

No to mamy pomysł jak zapamiętywać listę kuponów dla danej sumy. Teraz grubszy temat jak wygenerować wszystkie sumy. Na początek wybierzmy strukturę która by się do tego nadawała. Na pierwszy rzut oka lista nie wydaję się podejściem głupim. Tablica - nie bardzo, bo trzeba by zadeklarować 2^N komórek, bo przecież tyle jest kombinacji... ale po co, przecież zdublowanych sum zapisywać nie będziemy, te powyżej 10000 też na nic na się nie zdadzą. Dla wygody chciałbym też, aby nasza lista sum była posortowana, żeby łatwo można było sumy >10k usuwać. Przy użyciu tablicy będą tylko problemy z utrzymaniem jej porządku. Ok bierzemy listę.

  1. Na naszą listę L wpiszmy wartość 0.
  2. Jeżeli nie mamy kuponów to wychodzimy z algorytmu, a lista L zawiera wszystkie możliwe sumy.
  3. Weźmy jeden kupon i dodajmy do listy L wszystkie elementy z listy L powiększone o wartość kuponu.
  4. Wróćmy do punktu 2.

Zamieszane? Wcale nie, mały przykład:
Mamy takie kupony 1, 3, 4, 8, 10
Na początek L = [ 0 ].
Bierzemy pierwszy kupon (1) i dodajemy do listy L (0+1). L = [0,1].
Bierzemy kupon 3, dodajemy do listy (0+3), (1+3). L = [0,1,3,4].
Bierzemy kupon 4, dodajemy (0+4), (1+4), (3+4), (4+4). Ale przecież 4 jest już na liście więc to pomijamy, L = [0,1,3,4,5,7,8]
itd...

Prawda, że proste :) Teraz wystarczy przejrzeć listę L i zobaczyć czy jest na niej jakaś wielokrotność 1000PLN i kasa nasza. Dobrze by było wiedzieć jeszcze z jakich kuponów pozbierać tę okrągłą kwotę. O tym ja za jednym zamachem dodawać kupony do listy i rozszerzać listę o powiększone elementy będzie w komentarzach kodu. No właśnie implementacja... a niech będzie dzisiaj w C, żeby było szybko, a przy okazji sprawdzę czy umiem jeszcze implementować listę :)

#include <stdio.h>
#include <stdlib.h>

// Definicja elementu jednokierunkej listy przechowującej Kupony
typedef struct kupon {
  int value;
  struct kupon * next;
} elKupon;

// Definicja elementu dwukierunkwej listy przechowującej możliwe do utworzenia sumy
typedef struct element {
  int value;
  elKupon * kupon;
  struct element * next;
  struct element * prew;
} elList;

// Tworzy i inicjuje listę sum;
elList * makeList() {
  elList * l;
  l = malloc(sizeof(elList));
  l->value = 0;
  l->kupon = NULL;
  l->next = NULL;
  l->prew = NULL;
  return l;
}

// rozszerza listę o elementy elementy tejże listy powiększone o wartość add
void mergeAddList(elList * list, int add) {
  elList *l,*p,*n;
  elKupon * pk, *nk;
  int nv;
  
  // przyjmujemy tylko wartosci wieksze od zera
  if (add <= 0)
    return;
    
  // kopiujemy wskaznik na liste
  l = list;
  
  // przesuwamy wskaznik na koniec listy
  // przegladamy listę od konca, tj. od elementow najwiekszych
  // aby nowo dodawane elementy lądowaly na liście za rozpatrywaną wartoscia
  // nie potrzeba przez to tworzyć tymczasowej listy dodawanych elementow
  while (l->next != NULL)
    l = l->next;
  
  // kopiujemy wskaznik konca listy do p
  p = l;
    
  // dopuki p wskazuje na jakas wartosc
  // mamy jakies wartosci do powiekszenia i dodania do listy
  while (p != NULL) {
  
    // nowa wartosc do dodania
    nv = p->value + add;
    
    // lista kuponow tworzacych poprzednia wartosc
    nk = p->kupon;
    
    // przesuwamy sie o pozycje wstecz
    // (potrzebne wartosci juz skopiowalismy powyzej)
    p = p->prew;
    
    // jezeli nowa wartosc jest wieksza niz 10000 pomijamy ja
    // amino nie wyplaca takich kwot :)
    if (nv > 10000) 
      continue;
    
    // przesuwamy l wstacz dopuki wartosc na liscie bedzie 
    // mniejsza lub rowna nowej wartosci
    while (l->value > nv)
      l = l->prew;

    // jezeli nowa wartosc jest już na liści pomijamy ją
    if (l->value == nv)
      continue;
    
    // tworzymy nowy element listy z naszą nową wartosci
    n = malloc(sizeof(elList));
    n->value = nv;
    n->prew = l;
    n->next = l->next;
    
    // jeżeli istnieje element wiekszy od dodawanego
    // informujemy go ze ma nowego poprzednika
    if (l->next)
      l->next->prew = n;
      
    // dodajemy nowo utworzony element do listy 
    l->next = n;      
    
    // tworzymy nowy wpis dla kuponu
    pk = malloc(sizeof(elKupon));
    pk->value = add;
    // jaki kolejne elementy listy koponów tworzacych nowo dodana sume
    // stanowi ten kupon i lista skopiowana z p->kupon
    pk->next = nk;
    // dodajemy liste kuponow do nowo dodanej sumy
    n->kupon = pk;
  }
}

int main() {
  int r;  
  elList * list, *t;
  elKupon * pk;
  
  // tworzymy listę zawierajaca jedynie sume wartosci 0 
  list = makeList();
    
  // dopuki mozemy, czytamy ze standardowego wejscia liczby 
  while (scanf("%d", &r) == 1) {
    // rozszerzamy listę elementów o elementy tabliczy list powiekszone o r
    mergeAddList(list, r);
  }
  
  r = 0; // mowi o ty czy coś znaleźlismy
  
  // przegladamy liste
  t = list; 
  while (t) { 
    // jezeli cos nie dzieli sie przez 1000 bez reszty i nie jest 0
    // czyli nie jest wielkokrotnosci tysiaca
    // nie interesuje nas - przechodzimy dalej
    if (t->value % 1000 || t->value == 0) {
      t = t->next;
      continue;
    }
    
    // znalexlismy cos
    r = 1;
    printf("Masz %d PLN złożone z nastepujacych kuponow:\n", t->value);
    
    // wypisjemy kupony
    pk = t->kupon;
    while (pk) {
      printf("\t%d\n", pk->value);
      pk = pk->next;
    }
    
    // przechodzimy do nastepnej sumy
    t=t->next;
  }
  
  // jezeli nic nie znajdziemy - informujemy o tym z zalem 
  if (0 == r)
    printf("Nic jeszcze nie uzbierales :(\n");
  
  // aby było eleganco nalezaloby zwolnić pamiec explicite :)
  // ale system sobie poradzi :)
  
  return 0;
}


Dodano: 2009-11-30 07:53:13 | komentarze (1)

Poniedziałek... nie wiem, co jest z tymi poniedziałkami, ale strasznie demotywująco wpływa na mnie sama nazwa tego dnia tygodnia... ale do rzeczy. Poniedziałek (6 lipca) wszedłem sobie na stronę jednej z regionalnych gazet, by zobaczyć co w trawie piszczy po pięknym letnim weekendzie. Pech chciał, że wpisałem adres strony ręcznie... a że omylna ze mnie osoba wyszło tak:

http://www.pomorska.pl/apps/pbcs.dll/section?Category=BYGOSZC

... no trochę mało, (tak na marginesie... żeby takiej dużej firmie jak Media Regionalne Sp. z o.o. nie chciało się zainwestować chwili czasu swoich programistów na zaaplikowania mod_rewrite to co najmniej ciekawe), ale ku memu zdziwieniu nie dostałem kolejnego demotywatora pod tytułem "404" tylko coś zupełnie innego:

Pomyślałem sobie... a może da się tam wpisać troszkę więcej... niestety dało się. Co prawda, początkowo wszystko co niebezpieczne było sleszowane albo usuwane, jednak bajt 0x00 owe zabezpieczenia skutecznie wyłączył. Co więcej wartość zmiennej Category była (mocne słowo) wstawiana również wewnątrz znaczników <script></script> w kodzie HTMLa... co w konsekwencji dało bardzo prosty XSS.

http://www.pomorska.pl/apps/pbcs.dll/section?Category=B%00%22);alert(%22XSS

Grzeczny ze mnie chłopiec, więc zgłosiłem błąd przez formularz kontaktowy i dwie godzinki później napisał do mnie Kierownik Serwisów Internetowych (dumnie brzmi) z prośbą o opisanie szczegółów znalezionego błędu, co uczyniłem. Niestety mamy dzisiaj piątek drugiego tygodnia roboczego... błąd na stronie dalej jest. Jest to doskonały przykład, jak bardzo ważne jest bezpieczeństwo użytkownika dla spółki Media Regionalne. Bo dopóki nikt tego nie wykorzysta, lub konkurencja nie napisze kilku ciętych słów nikt palca do klawiatury nie ruszy, bo poco. "Jeden pryszczaty nastolatek nam nic nie zrobi" - ciekawe podejście.



Dodano: 2009-07-17 12:46:23 | komentarze (0)

TCPDF jest bardzo wygodną klasą do generowania plików PDF. Nie będę się tu rozpisywał na temat jej zalet, a skupię się wyłącznie na jednym problemie. Klasa ta, bardzo pięknie obsługuje czcionki unicode w tym takie z polskimi znakami. Problem w tym, że czcionki te mają dość duży rozmiar i po dołączeniu ich do pdfa skutkują jego dość pokaźną nadwagą. Po zastosowaniu diety i wygenerowaniu pliku czcionki z mapą znaków tylko iso-8859-2 jesteśmy niejako zmuszeniu do tworzenia obiektu klasy TCPDF jak nie unicode oraz z charsetem iso-8859-2 i konwertowania wszystkich tekstów z utf8 na iso-8859-2 gdyż sama klasa zdecydowanie sobie z tym nie radzi. Moje rozwiązanie tego problemu przedstawia się następująco:
  1. Generujemy odchudzony plik czcionek:
    $ ttf2ufm -b -L iso-8859-2.map times.ttf times
    $ php -q makefont.php times.pfb timesbi.afm iso-8859-2
  2. Następnie dopisujemy rozmiary polskich znaków dialektycznych do pliku times.php (z lenistwa kopiując wartości ze znaczków bez ogonków. Oto fragment pliku times.php:
    250=>500,251=>500,252=>500,253=>500,254=>278,255=>333);
    
    $cw[260] = $cw[65]; // A
    $cw[261] = $cw[97]; // a
    $cw[262] = $cw[67]; // C
    $cw[263] = $cw[99]; // c
    $cw[280] = $cw[69]; // E
    $cw[281] = $cw[101]; // e
    $cw[321] = $cw[76]; // L
    $cw[322] = $cw[108]; // l
    $cw[323] = $cw[78]; // N
    $cw[324] = $cw[110]; // n
    $cw[211] = $cw[79]; // O
    $cw[243] = $cw[111]; // o
    $cw[346] = $cw[83]; // S
    $cw[347] = $cw[115]; // s
    $cw[377] = $cw[90]; // Z
    $cw[378] = $cw[122]; // z
    $cw[379] = $cw[90]; // Z
    $cw[380] = $cw[122]; // z
    
    $enc='iso-8859-2';
    
  3. wrzucamy pliki times.php oraz times.z do katalogu czcionek TCPDFa
  4. No i teraz najlepsze - tworzymy klasę która dziedziczy po TCPDF i nadpisujemy jedną metodę:
    class TCPDFpl extends TCPDF {
      protected function UTF8ToLatin1($str) {
        if (!$this->isunicode) {
          return $str;   
        }
        return iconv("UTF-8", "ISO-8859-2", $str);
      }                    	
    }
    
  5. No i cieszymy się pięknymi ogonkami :)
    $pdf = new TCPDFpl(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8');
    $pdf->setFont('times', '', 10);
    $pdf->addPage();
    $pdf->cell(0, 20, 'O, mógłże sęp chlań wyjść furtką bździn.');
    


Dodano: 2009-03-04 17:16:37 | komentarze (3)

Problem występuje w przeglądarce IE7 w przypadku próbie przetwarzania zapytania XMLHttpRequest. Rzecz w tym, że przeglądarka nie rozumie kodowania "utf8" lub innego nie zdefiniowanego w dokumencie http://www.iana.org/assignments/character-sets. Jeżeli kodujesz w PHP, rozwiązaniem problemu jest ustawienie default_charset na "UTF-8" bądź nadpisać nagłówek Content-Type.
<?php
ini_set('default_charset','UTF-8'); // rozwiązanie #1
header('Content-Type', 'text/html; charset=UTF-8'); // rozwiązanie #2
?>


Dodano: 2008-12-02 15:14:25 | komentarze (1)

Tell me why the stars do shine,
Tell me why the ivy twines,
Tell me why the sky's so blue,
And I will tell you just why I love you.

	Nuclear fusion makes stars to shine,
	Phototropism makes ivy twine,
	Rayleigh scattering makes sky so blue,
	Sexual hormones are why I love you.


Dodano: 2008-04-18 02:02:04 | komentarze (0)

Któregoś lipcowego wieczora, coś mnie tknęło i przyjrzałem się stronie Mojej Generacji (http://www.mojageneracja.pl) pod kontem niedociągnięć w kodzie. I tak: Stronka bardzo ładna w technologii (jak to się ładnie nazywa) Web2, kolorowa, z mnóstwem bajerów i wodotrysków. Napisana w PHP :) do tego jakiś mod_rewrite (lub coś w ten deseń). Nie było problemem by dojść do tego, ze zapytania o dana stronę przepisywana są do index.php?page=i_tu_co_ma_sie_wyswietlic. Następne moje spostrzeżenie było takie, że zmienna $_GET['page'] jest wstawiana do kodu strony jako nazwa klasy css definiująca wygląd elementów na danej stronie. Np.:
Strona http://www.mojageneracja.pl/index.php?page=Start zawiera takie elementy jak:
<body class="Start-body">
(...)
<div class="interline interline-Start">
i tym podobne. w związku z czy spróbowałem się z tą zmienną troszeczkę pobawić :)

Udało mi się wstrzyknąć kod javascript np. w znacznik body takim linkiem:
http://www.mojageneracja.pl/index.php?page=foo%22%20onload=%22alert('bar')%22%20

Gdy miałem już pewność, że dzięki temu można przeprowadzić atak wędkarski na konta gadu-gadu, próbowałem skontaktować się z załogą Mojej Generacji. Zacząłem od Pana Jurka czyli człowieka który służy pomocą na tym portalu. Nie uzyskałem żadnej odpowiedzi. Wiec wysłałem maila, na adres generacji, z prośbą o kontakt z osobą odpowiedzialną za bezpieczeństwo portalu. Odpowiedz przyszła dnia następnego od Pana któremu wszystko ładnie wytłumaczyłem. Reakcja była bardzo szybka. Już tego samego dnia wieczorem odkryty przeze mnie błąd był załatany.

Na koniec pozdrowienia dla całego zespołu Mojej Generacji.

Dodano: 2007-08-03 00:00:44 | komentarze (2)

Tak wiec tego popołudnia postanowiłem pobawić się troszeczkę Berylem. Z racji tego, ze posiadam kartę ATI nie obyło się bez problemów. Po zamianie sterowników fglrx o opensourcowe i odpaleniu "stabilnej" wersji beryla, ujrzałem "White screen of death". Po dosyć długim googlowaniu, czytaniu przerożnych list dyskusyjnych, próbach z --use-copy i innych, podłamany brakiem oczekiwanych rezultatów, postanowiłem zainstalować wersje z CVS. Ku mojemu zaskoczeniu, ta zadziałała bez najmniejszych problemów. Wrażenia: Rewelacja, super kolorowy bajer, przezroczystość to nic. Na moim Radeonie 9600 mam najmniej 60 fpsów (średnio 90). Polecam.

Dodano: 2007-04-17 20:18:57 | komentarze (1)

Oto sposób jak zarobić 40PLN. Mianowicie: kabel do APC Smarta koszuje 15$ (15 baksów ~ 46 PLN). Ja namoj wydałem 6PLN w pobliskim sklepie z podzespolami. Tylko, ze ten moj to zwykly przedluzacz COM. Po kilku poprawkach (Opis) apcupsd dogaduje sie z bateryjka bez najmniejszych problemów.

Dodano: 2006-09-26 19:15:46 | komentarze (5)

Wes Borg:
I'll give you a cake, I'll give you a hug,
I'll buy the world's best System Administrator mug.
Just help me out, system administrator.
Please plug in my mouse, system administrator.
I don't know which button is the mouse click button, system administrator.


Dodano: 2006-07-28 10:39:03 | komentarze (1)

W chwile wolnego czasu postanowilem zrobic cos tak głupiego jak blog. Nie wiem co mna kierowało, chyba wzmozona aktywnosc slonca za bardzo zadzialala na moja glowe. Tak czy inaczej jest. Moze jeszcze nie dziala, tak jak bym sobie tego zyczyl, ale dziala.

Dodano: 2006-07-27 15:18:51 | komentarze (4)


Slackware Linux Valid XHTML 1.1 Valid CSS Nowoczesne przeglądarki Creative Commons License Spamerom mowimy NIE! HandCoded hacker-emblem website uptime Zobacz mnie na GoldenLine