abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 01:11 | Nová verze

    UBports, nadace a komunita kolem Ubuntu pro telefony a tablety Ubuntu Touch, vydala Ubuntu Touch 24.04-1.2 a 20.04 OTA-12.

    Ladislav Hagara | Komentářů: 0
    včera 18:00 | Nová verze

    Byla vydána (Mastodon, 𝕏) nová stabilní verze 2.0 otevřeného operačního systému pro chytré hodinky AsteroidOS (Wikipedie). Přehled novinek v oznámení o vydání a na YouTube.

    Ladislav Hagara | Komentářů: 1
    včera 16:00 | Zajímavý software

    WoWee je open-source klient pro MMORPG hru World of Warcraft, kompatibilní se základní verzí a rozšířeními The Burning Crusade a Wrath of the Lich King. Klient je napsaný v C++ a využívá vlastní OpenGL renderer, pro provoz vyžaduje modely, grafiku, hudbu, zvuky a další assety z originální kopie hry od Blizzardu. Zdrojový kód je na GitHubu, dostupný pod licencí MIT.

    NUKE GAZA! 🎆 | Komentářů: 4
    včera 13:33 | IT novinky

    Byl představen ICT Supply Chain Security Toolbox, společný nezávazný rámec EU pro posuzování a snižování kybernetických bezpečnostních rizik v ICT dodavatelských řetězcích. Toolbox identifikuje možné rizikové scénáře ovlivňující ICT dodavatelské řetězce a na jejich podkladě nabízí koordinovaná doporučení k hodnocení a mitigaci rizik. Doporučení se dotýkají mj. podpory multi-vendor strategií a snižování závislostí na vysoce

    … více »
    Ladislav Hagara | Komentářů: 4
    včera 12:22 | Humor

    Nizozemský ministr obrany Gijs Tuinman prohlásil, že je možné stíhací letouny F-35 'jailbreaknout stejně jako iPhony', tedy upravit jejich software bez souhlasu USA nebo spolupráce s výrobcem Lockheed Martin. Tento výrok zazněl v rozhovoru na BNR Nieuwsradio, kde Tuinman naznačil, že evropské země by mohly potřebovat větší nezávislost na americké technologii. Jak by bylo jailbreak možné technicky provést pan ministr nijak nespecifikoval, nicméně je známé, že izraelské letectvo ve svých modifikovaných stíhačkách F-35 používá vlastní software.

    NUKE GAZA! 🎆 | Komentářů: 21
    včera 06:00 | Zajímavý článek

    Nové číslo časopisu Raspberry Pi zdarma ke čtení: Raspberry Pi Official Magazine 162 (pdf).

    Ladislav Hagara | Komentářů: 0
    včera 05:55 | IT novinky

    Sdružení CZ.NIC, správce české národní domény, zveřejnilo Domain Report za rok 2025 s klíčovými daty o vývoji domény .CZ. Na konci roku 2025 bylo v registru české národní domény celkem 1 515 860 s koncovkou .CZ. Průměrně bylo měsíčně zaregistrováno 16 222 domén, přičemž nejvíce registrací proběhlo v lednu (18 722) a nejméně pak v červnu (14 559). Podíl domén zabezpečených pomocí technologie DNSSEC se po několika letech stagnace výrazně

    … více »
    Ladislav Hagara | Komentářů: 9
    18.2. 18:33 | IT novinky

    Google představil telefon Pixel 10a. S funkci Satelitní SOS, která vás spojí se záchrannými složkami i v místech bez signálu Wi-Fi nebo mobilní sítě. Cena telefonu je od 13 290 Kč.

    Ladislav Hagara | Komentářů: 7
    18.2. 16:22 | Komunita

    Byl publikován přehled dění a novinek z vývoje Asahi Linuxu, tj. Linuxu pro Apple Silicon. Fedora 43 Asahi Remix s KDE Plasma už funguje na M3. Zatím ale bez GPU akcelerace. Vývojáře lze podpořit na Open Collective a GitHub Sponsors.

    Ladislav Hagara | Komentářů: 0
    18.2. 14:00 | IT novinky

    Red Hat představil nový nástroj Digital Sovereignty Readiness Assessment (GitHub), který organizacím umožní vyhodnotit jejich aktuální schopnosti v oblasti digitální suverenity a nastavit strategii pro nezávislé a bezpečné řízení IT prostředí.

    Ladislav Hagara | Komentářů: 0
    Které desktopové prostředí na Linuxu používáte?
     (18%)
     (6%)
     (0%)
     (11%)
     (27%)
     (3%)
     (5%)
     (2%)
     (12%)
     (27%)
    Celkem 908 hlasů
     Komentářů: 25, poslední 3.2. 19:50
    Rozcestník

    Skeldal a autoconf

    9.3.2011 16:52 | Přečteno: 1319× | Linux

    Tentokrát jsem se vrtal v build systému Skeldalu a dodělal dlouho slibovanou možnost nastavit cesty k datovým souborům přes configure skript. Má to ale jeden háček: od revize 160 se mění defaultní cesta k datovým souborům hry.

    Při updatu na nejnovější revizi tak máte na výběr ze dvou možností: Buď si herní data přesunete/nasymlinkujete do adresáře /usr/local/share/skeldal, nebo budete spouštět configure skript takto:

    ./configure --datadir='${prefix}/games'

    Pokud někdo víte, jak autoconf rozumným způsobem donutit změnit default proměnné ${datadir} na ${prefix}/games, rád si nechám v diskuzi poradit. Hlavní podmínka je, že tahle změna musí bez vnějšího zásahu přežít následný autoreconf.

    Další změny od minula jsou spíše technického charakteru. První změna potěší autory dobrodružství, protože nový kód na načítání textů korektně řeší spoustu okrajových případů, na kterých by předchozí kód zbytečně selhal. Navíc teď správně hlásí číslo řádku, na kterém je chyba. Druhá změna potěší majitele starších strojů. Pokusil jsem se zoptimalizovat nejvytíženější renderovací funkce a všechny kromě jedné se mi podařilo zrychlit skoro na dvojnásobek. Změna se ale projeví jen zvýšením frameratu. Kvůli implementaci hlavní smyčky podle všeho hra místo častějšího uspání jen častěji kreslí. Někdy se budu muset do vnitřností hry podívat trochu hlouběji a konečně pořádně oddělit vykreslování od přepočítávání herního stavu.

    Do první stabilní verze portu tak zbývá už jen mapování kláves a dořešení několika technických drobností.

           

    Hodnocení: 100 %

            špatnédobré        

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    Jardík avatar 9.3.2011 17:01 Jardík | skóre: 40 | blog: jarda_bloguje
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Navrhuji řešení použít environment proměnné XDG_DATA_HOME a XDG_DATA_DIRS (s příslušnými fallbacky dle freedesktop "standardu") a pokud nikde data nejsou, tak teprve poté přistoupit k použití hardkódované cesty nastavené configure skriptem. Takové řešení je (podle mě) nejlepší.
    Věřím v jednoho Boha.
    9.3.2011 17:54 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Nikdo ti nebrání poslat patch. Jestli s tím budou lidé souhlasit a ten kód bude vypadat rozumně, tak nevidím důvod, proč to nezařadit.
    Jardík avatar 9.3.2011 20:01 Jardík | skóre: 40 | blog: jarda_bloguje
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Já ten program nepoužívám, ani nevím, k čemu to je. Já jen napsal, jak by to bylo podle mě nejlepší. Jestli to tak někdo chce/nechce, nebo jestli to tak někdo udělá/neudělá, mi je fakt jedno. Věta "Nikdo ti nebrání poslat patch" mi vyzní jako "trhni si nohou a nechtěj mi přidělávat starosti". Teď jsem kouknul do jednoho náhodného zdrojáku, spatřil myšlenku sizeof() vrací int a tak si o tomto projektu dále myslím své a mlčím :-)
    Věřím v jednoho Boha.
    9.3.2011 20:05 polymorf | skóre: 14 | blog: tar_zxpf
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    +1 tiež ma jeho odpoveď trochu šokovala, myslel som že sa pýta ako na to.
    vain avatar 9.3.2011 20:08 vain | skóre: 16
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    No evidentně ptal.
    rád si nechám v diskuzi poradit
    If the only choice you've got is to do the wrong thing, then it's not really the wrong thing, it's more like fate.
    10.3.2011 00:08 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf

    Co je šokujícího na tom, že na feature request, který nemá nijak zásadní vliv na funkčnost hry, odpovím "tak to napiš sám a pošli mi patch"? Ze 144 commitů v mojí větvi jsou jen tři patche od někoho jiného, z toho jeden jsou ikonky a další jsem musel sám z poloviny přepsat, protože autor se mi na žádost o vylepšení patche už neozval.

    BTW, měl bych Jardíkovi poděkovat. Při opravování typů proměnných a návratových hodnot, co přímo pracují se sizeof, se mi podařilo najít a opravit jeden bug v pointerové aritmetice.

    10.3.2011 08:39 polymorf | skóre: 14 | blog: tar_zxpf
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Jak som pochopil tento blog:

    Ty: Program skeldal, nieco zmenili a neviem ako upravit konfigurak aby nacitaval data z ineho miesta. Neviete niekto ako na to?

    Jardik: Myslim ze by stacilo upravit premennu X a Y.

    Ty: Nikdo ti nebrání poslat patch.
    10.3.2011 09:36 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Tak to jsi pochopil špatně. Tuhle změnu ve Skeldalu jsem spáchal já, a tohle je v podstatě changelog, aby se uživatelé nedivili, že jim Skeldal najednou odmítá načítat data. Dotaz byl na znalce Autoconfu co napsat do configure.ac, aby build systém defaultně hledal data na starém místě i bez zásahu uživatele.
    10.3.2011 09:57 polymorf | skóre: 14 | blog: tar_zxpf
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Aj tak znies ako buran:

    Ty: Upravil som cestu dat v programe skeldal, neviem ako upravit configure.ac aby nacitaval data zo spravneho miesta. Neviete niekto ako na to?

    Jardik: Myslim ze by stacilo upravit premennu X a Y.

    Ty: Nikdo ti nebrání poslat patch.
    10.3.2011 10:19 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    V tom případě jsi nepochopil ani Jardíkův komentář. XDG_* tenhle problém nevyřeší, protože na různých strojích můžou mít různý obsah. Jardík jenom prudí s dalším Jediným® Správným© Řešením™, navíc na úplně jiný problém.
    Jardík avatar 10.3.2011 14:09 Jardík | skóre: 40 | blog: jarda_bloguje
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Tedy jsem ti opravil fci (idx by si zasloužilo být size_t, ale ...:
    // skeldal/branches/next_ghost/unix/init.cpp
    
    void Sys_SetPath(unsigned idx, const char *path) {
    	size_t len = strlen(path); // tady byl int
    	assert(idx < PATHTABLE_SIZE);
    
    	if (pathtable[idx]) {
    		free(pathtable[idx]);
    	}
    
    	// tady nebyl test *path == 0, což mohlo způsobit pád v kódu
    	// níže, protože len-1 by šlo na neplatný index SIZE_MAX
    	if (!*path || *path == 0) { 
    		pathtable[idx] = (char*)malloc(1);
    		pathtable[idx][0] = '\0';
    		return;
    	}
    
    	if (path[len - 1] != '/') {
    		len++;
    	}
    
    	pathtable[idx] = (char*)malloc(len + 1);
    	strcpy(pathtable[idx], path);
    	pathtable[idx][len-1] = '/';
    	pathtable[idx][len] = '\0';
    }
    
    Ještě tam teda chybí kontrola návratových hodnot z malloc(), to už se mi nechce dělat.

    Další chyby:
    // není reentrant
    char *Sys_FullPath(unsigned idx, const char *file) {
    	static char ret[PATH_MAX];
    	assert(idx < PATHTABLE_SIZE);
    	// tady může dojít k přetečení fixně velikého bufferu
    	strcpy(ret, pathtable[idx]);
    	strncat(ret, file, PATH_MAX - strlen(ret) - 1);
    	return ret;
    }
    
    // není reentrant
    char *Sys_DOSPath(unsigned defdir, const char *path) {
    	static char ret[PATH_MAX];
    	int i, length;        // "má" být size_t
    	assert(defdir < PATHTABLE_SIZE);
    
    	// možnost přetečení bufferu
    	strcpy(ret, pathtable[defdir]);
    	length = strlen(ret);
    	strncat(ret + length, path, PATH_MAX - length - 1);
    	strupr(ret + length);
    
    	for (i = length; ret[i]; i++) {
    		if (ret[i] == '\\') {
    			ret[i] = '/';
    		}
    	}
    
    	return ret;
    }
    
    void Sys_Init(void) {
    	char home[PATH_MAX]; // smyšlená hodnota maximální velikosti cesty
    	int len; // size_t
    	// možnost přetečení bufferu, getenv() může vrátit NULL
    	strcpy(home, getenv("HOME"));
    	len = strlen(home);
    	// neplatný index při len == 0
    	if (home[len-1] != '/') {
    		home[len++] = '/';
    	}
    	// další možnost přetečení bufferu
    	strcpy(home + len, ".skeldal/");
    
    Nakonec dotaz: znáš třeba std::map a std::string? Když je to C++ kód, proč to nepoužít? Ušetřil bys si spoustu starostí, např. Sys_SetPath by mohl vypadat nějak takto:
    typedef std::map<unsigned, std::string> Mapa;
    Mapa mapa;
    
    void Sys_SetPath(unsigned id, const std::string& path)
    {
      std::string& oldVal = mapa[id];
      std::string::size_type len;
      oldVal = path;
      len = oldVal.size();
      if (len > 0 && oldVal[len-1] != '/') oldVal += '/';
    }
    
    A při chybné alokaci ti to prostě vyprskne std::bad_alloc
    Věřím v jednoho Boha.
    Jardík avatar 10.3.2011 14:17 Jardík | skóre: 40 | blog: jarda_bloguje
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Příloha:
    BTW máš co dělat, tady je log z kompilace (prsknul jsem tam -Wall -pedantic):
    Věřím v jednoho Boha.
    10.3.2011 16:47 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Hezké. Jenže většina těch problémů je v původním kódu z roku 1997. Opravovat to budu průběžně až na daný kus kódu přijde řada.
    10.3.2011 16:43 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Zformátuj to a pošli to jako patch, ať jsou vidět změny. STL znám a odmítám to použít, protože bych tím akorát zablokoval možnost portovat Skeldal na mobilní platformy s omezenou pamětí.
    Jardík avatar 10.3.2011 21:24 Jardík | skóre: 40 | blog: jarda_bloguje
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    STL znám a odmítám to použít, protože bych tím akorát zablokoval možnost portovat Skeldal na mobilní platformy s omezenou pamětí.
    To je škoda. Já si trochu procházel ten kód a místama jsou tam takové čuňárny a je to tak nepřehledné, všude možně chybí kontrola chyb, některé funkce vůbec neupozorní na chyby (ani nějakým kódem, ani výjimkou, ani vypsáním) a vypadá to fakt neudržitelně. Ale snaha se cení.
    Věřím v jednoho Boha.
    12.3.2011 09:02 Vin
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    A STL by těm čuňárnám nějak zamezilo?

    Jinak sám autor napsal, že by to dnes řešil jinak - http://www.root.cz/clanky/rozhovor-s-ondrejem-novakem-vyvojarem-hry-brany-skeldalu/

    otázkou je, jestli by se tehdy stihnul deadline pro vydání hry, než by se to naučil (navíc, jak zmiňuje v rozhovoru, potřeboval řešit jiné problémy, které dnes už asi nejsou).

    Bedňa avatar 12.3.2011 15:52 Bedňa | skóre: 34 | blog: Žumpa | Horňany
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Mirek Fidler o STL:
    Proč děláme takovou hloupost? Stručná, byť možná trochu nesrozumitelná, odpověď na tuto otázku by se dala shrnout do věty: "Protože STL vás nutí si přát, aby C++ mělo automatickou správu paměti (garbage collector - GC)".

    Problém je v tom, že do STL kontejneru můžete vkládat pouze objekty, které mají definovanou kopii. Navíc, pokud aspoň trochu dbáte na rychlost aplikace, musí tato kopie pokud možno být jednoduše proveditelná (rychlá).

    To v praxi znamená, že do STL kontejneru je možné efektivně ukládat fundamentální typy, možná ještě tak řetězce a pár dalších jednoduchých typů. Všechno ostatní lze uložit pouze nepřímo pomocí ukazatele. Tím se ztrácí jedna ze základních výhod, kterou používaní kontejnerových šablon přináší - automatická správa paměti.
    KERNEL ULTRAS video channel >>>
    Jardík avatar 13.3.2011 04:21 Jardík | skóre: 40 | blog: jarda_bloguje
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    V C++0x to řeší move constructor.
    Věřím v jednoho Boha.
    Bedňa avatar 10.3.2011 18:30 Bedňa | skóre: 34 | blog: Žumpa | Horňany
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Hackery sa takto bavia bežne, keď nevieš o čom je reč tak sa nezapájaj, sa čudujem že Martin na teba vôbec reagoval.
    KERNEL ULTRAS video channel >>>
    stativ avatar 9.3.2011 20:09 stativ | skóre: 54 | blog: SlaNé roury
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Řekl bych, že vzhledem k tomu, z jakých zdrojáků to vzešlo je to detail a cením si práce, které na tom Martin udělal, aby to vůbec fungovalo s moderními systémy.
    Ať sežeru elfa i s chlupama!!! ljirkovsky.wordpress.com stativ.tk
    9.3.2011 23:05 Drew | skóre: 15 | blog: Supi_hnizdo | Praha
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    Hm, to by se ale týkalo ledatak uložených pozic a nastavení (je ve skeldalu vůbec nějaké?) - herní data by přece měla být nainstalována ne v domovském adresáři nějakého uživatele ale někde, kde jsou dostupná všem, ne?
    10.3.2011 00:13 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    XDG_DATA_DIRS má na mém stroji hodnotu /usr/share:/usr/local/share:/usr/share a XDG_DATA_HOME nemám nastavenou vůbec. Tyhle proměnné jsou dobré tak akorát pro proprietární soft, aby se dal instalovat na víc možných míst. Skeldal je open source a od začátku mám v plánu protlačit do repozitářů minimálně Gentoo a Debianu, takže takovou věc nepotřebuje.
    10.3.2011 10:55 Scarabeus IV | skóre: 20 | blog: blogisek_o_gentoo | Praha
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    A ty beres jaky drogy chlape, i kdyz se Jardik vetsinou chova jako idiot tak ma pravdu.

    XDG je freedesktop specifikace...

    A nyni par veci k autotools:
    1) v repozitari se ponechavaji pouze Makefile.am a configure.{ac,in} zbytek je generovan pouze pro release.
    2) proc nepouzivas pkgconfig kdyz hledas sdl a sdl-mixer: PKG_CHECK_MODULES(SDL, sdl sdl-mixer) a pak se pouzije v Makefile.am skeldal_LDADD = $(SDL_LIBS) skeldal_CXXFLAGS=$(SDL_CFLAGS) nebo tak nejak. 3) zadratovat cestu v prubehu configure je sakrapekna prasarna viz XDG specifikace vejs, ale pokud po tom touzis tak se vyplati tam dat neco jako --with-gamedata=/path do configure, a to predat do Makefile.am nez redefinovat datadir.
    4) CPPFLAGS jsou nastaveni pro C Pre Processor ne pro C++ to je CXXFLAGS.
    5) Chybi tam autogen.sh na generovani configure/Makefile, viz bod 1.

    ad 3)
    AC_ARG_WITH(gamedata-prefix,
    	[AS_HELP_STRING([--with-gamedata-prefix=PREFIX], [Prefix for game data.])],
    )
    ad 5)
    set -e
    : ${AUTORECONF:=autoreconf}
    if test "$*"; then
    	ARGS="$*"
    else
    	if test -f config.log ; then
    		ARGS=`grep '^  \$ \./configure ' config.log | sed 's/^  \$ \.\/configure //' 2> /dev/null`
    	fi
    fi
    
    echo "Running ${AUTORECONF}..."
    $AUTORECONF --install --verbose
    test x$NOCONFIGURE = x && echo "Running ./configure $ARGS" && ./configure $ARGS
    10.3.2011 11:57 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf

    ad 1) a 5) Neznám moc balíků, které by tohle dělaly, a UNIXový standard je ./configure; make; make install. Dokud se ze "svaté trojice" nestane čtveřice, která začíná ./autogen.sh nebo něčím podobným, budu mít configure skript přímo v repozitáři, stejně jako většina ostatních projektů. Navíc takový skript GNU Coding Standards nevyžaduje.

    ad 2) Díky za tip, tohle jsem neznal.

    ad 3) Podle GNU Coding Standard je to zcela v pořádku a já se s dovolením budu držet GNU Coding Standards. Freedesktop si může vymýšlet, co chce, ale to ještě neznamená, že to má smysl používat.

    ad 4) -Dcosi je flag preprocesoru, takže AM_CPPFLAGS je naprosto správné umístění. CPPFLAGS se používá při kompilaci C i C++, CXXFLAGS jen pro C++.

    10.3.2011 12:12 Scarabeus IV | skóre: 20 | blog: blogisek_o_gentoo | Praha
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    1 az 5) Podivej se na cgit.freedesktop.org nebo http://git.gnome.org/browse/.

    3) Prekvapive tahle prkotina kterou oznacujes za vymyslenost kterou nema smysl pouzivat je pouzivana vsemy DE aprotoze se dodrzuje na vsech platformach stejne. Zaroven uz to nastesti zacina podporovat spousta 3rd party aplikaci taky takze treba v home slozkach prestane bejt tak nechutnej bordel.

    4) no ja se ani nekoukal co v ni je, vetsinou je pouzita blbe, v tomhle pripade bych ovsem spis sel do skeldal_CPPFLAGS nez to nastavovat globalne :)
    10.3.2011 12:47 Martin Doucha | skóre: 23 | blog: Yet another blog
    Rozbalit Rozbalit vše Re: Skeldal a autoconf
    ad 3) DE to implementovat musí, jinak celá tahle ptákovina nebude fungovat. Já ale portuju hru, ne DE.

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.