<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>J3tBoy</title><generator>teletype.in</generator><description><![CDATA[J3tBoy]]></description><image><url>https://img1.teletype.in/files/83/29/83290dce-ca3f-4e30-a3a4-e1425f3d1547.png</url><title>J3tBoy</title><link>https://teletype.in/@j3tboy</link></image><link>https://teletype.in/@j3tboy?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/j3tboy?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/j3tboy?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Thu, 25 Jun 2026 04:08:44 GMT</pubDate><lastBuildDate>Thu, 25 Jun 2026 04:08:44 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@j3tboy/nintendo_2ds_cia</guid><link>https://teletype.in/@j3tboy/nintendo_2ds_cia?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy</link><comments>https://teletype.in/@j3tboy/nintendo_2ds_cia?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy#comments</comments><dc:creator>j3tboy</dc:creator><title>Инструкция по запуску игр на Nintendo 3DS.</title><pubDate>Tue, 10 Oct 2023 19:39:17 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/96/ab/96ab70e3-ab88-4e59-8879-a0e19c82b46d.png"></media:content><tt:hashtag>3ds</tt:hashtag><tt:hashtag>2ds</tt:hashtag><tt:hashtag>nintendo</tt:hashtag><tt:hashtag>old_games</tt:hashtag><tt:hashtag>manuals</tt:hashtag><tt:hashtag>retro_games</tt:hashtag><tt:hashtag>retro</tt:hashtag><tt:hashtag>games</tt:hashtag><tt:hashtag>nintendo_ds</tt:hashtag><tt:hashtag>nintendo_3ds</tt:hashtag><tt:hashtag>nintendo_2ds</tt:hashtag><description><![CDATA[<img src="https://img2.teletype.in/files/dc/81/dc81846c-cd12-4e49-a4d7-4f625f640614.png"></img>Сегодня будет инструкция о способах запуска ромов на прошитой консоли nintendo 3ds.]]></description><content:encoded><![CDATA[
  <blockquote id="yEPi"><em>Сегодня будет инструкция о способах запуска ромов на прошитой консоли nintendo 3ds.</em></blockquote>
  <p id="nYyl">Мой интерес к этой консоли возник довольно давно, хотелось посмотреть, что это за портативка такая, с двумя экранами, 3d-эффектом и высоченным ценником. </p>
  <p id="qino">Приобрел я эту консоль только в 2023 году, до нее были GameBoy Advance, классический GameBoy, Nintendo DS fat, Nintendo Switch, несколько портативок от других производителей <strong>и наконец 2DS</strong>.</p>
  <p id="rUVY">Вот не сложилось пока посмотреть 3d-эффект, это в перспективе.</p>
  <p id="UwNc">2DS я купил случайно, попалось на авито очень интересное предложение, черно-синяя, в очень приличном состоянии и с прошивкой.</p>
  <figure id="SLyC" class="m_column">
    <img src="https://img2.teletype.in/files/dc/81/dc81846c-cd12-4e49-a4d7-4f625f640614.png" width="1280" />
  </figure>
  <p id="sWgp"></p>
  <p id="BKmi">Покупка прошито консоли для меня всегда интереснее, чем не прошитая по понятным причинам.</p>
  <p id="XDWJ">В моем случае, который является самым обычным, на консоль установлена Luma 3DS. Хорошая штука, не слетает при полном разряде батарейки (не проверял).</p>
  <p id="ovKQ">К основным особенностям относится:</p>
  <ul id="0q1M">
    <li id="2Art">запуск ромов, установка dlc;</li>
    <li id="kk0m">отключение региональной защиты;</li>
    <li id="LWSp">установка софта (эмуляторов и прочего);</li>
  </ul>
  <p id="4xuZ">Собственно, большего мне ничего от приставки и не нужно. Официальный он-лайн мне не актуален, да его и нет вроде как.</p>
  <h3 id="JOFK">Основные форматы rom для 3ds.</h3>
  <p id="j342">В отличии от других приставок, у 3ds ромы бывают нескольких видов:</p>
  <ul id="WndF">
    <li id="jSmS">cia - основной формат, запускаемых на Luma3DS;</li>
    <li id="AH8V">3ds - формат ромов для эмулятора citra;</li>
  </ul>
  <p id="Pc4M">Причем, более распространент как раз 3ds-формат, некоторые игры в cia просто не найти в инете и их придется конвертировать или играть на эмуляторе.</p>
  <h3 id="ZDbQ">Установка cia</h3>
  <p id="iFiH">С прошитой приставкой шла SD карточка на 16 гб, которая была забита всякой ерундой, типа марио, плюс, куча образов валялось разбросанная по папкам без всякой системы. </p>
  <p id="CQht">Некоторые игры довольно увесистые, по этому, карточку я заменил на 64-гигабайтную, чтоб хватило на все. </p>
  <p id="UVEl">Теперь опишим процесс установки ромов подробно через программу FBI:</p>
  <ul id="QICh">
    <li id="uCku">На прямую подключить к компьютеру 2DS нельзя, нужно вынимать SD-карту или настраивать ftp;</li>
    <li id="WhnU">Нужно поместить файлы формата cia в директорию /cias или /cia на sd-карте.</li>
    <li id="BgSN">Возвращаем карточку обратнов в приставку, включаем и запускаем FBI.</li>
  </ul>
  <figure id="oWyq" class="m_column">
    <img src="https://img1.teletype.in/files/4f/aa/4faa279d-c376-46b7-b43a-fc6c031a9490.png" width="1280" />
  </figure>
  <ul id="JAUz">
    <li id="jg7C">Выбираем раздел SD</li>
  </ul>
  <figure id="vUew" class="m_column">
    <img src="https://img1.teletype.in/files/44/38/44388df5-5f00-46ee-93dd-f882232792bd.png" width="1233" />
  </figure>
  <ul id="kVI5">
    <li id="LfGG">Переходим в раздел cias<br /></li>
  </ul>
  <figure id="QGql" class="m_column">
    <img src="https://img4.teletype.in/files/31/26/31263982-8ab0-4095-8582-42486d86e0cc.png" width="1280" />
  </figure>
  <ul id="G4bV">
    <li id="Iwd2">Там должен лежать устанавливаемый ром, выбираем его и нажимаем кнопку ( А ) на консоли.</li>
    <li id="3P5d">В разделе &quot;Directory Action&quot; выбираем пункт &quot;Install and delete CIAs&quot;, чтобы после установки ром был удален и не занимал память на карте.</li>
  </ul>
  <figure id="Chkd" class="m_column">
    <img src="https://img4.teletype.in/files/f0/b9/f0b94e32-c4dc-4bb3-af42-319090a5fc5f.png" width="1280" />
  </figure>
  <p id="E6CH">Собственно, это все, остается дождаться установки рома, <strong>NEW SOFTWARE HAS BEEN ADDED</strong>, после чего нажать кнопку &quot;Home&quot;, иконка игры появится в главном меню.</p>
  <p id="rOvZ">С добавлением разобрались, теперь посмотрим, как удалить установленный ром.</p>
  <h3 id="0Zpv">Удаление cia</h3>
  <p id="MBpE">Удалять можно через FBI, но проще через системные настройки.</p>
  <figure id="0wHH" class="m_column">
    <img src="https://img2.teletype.in/files/1c/9c/1c9c3f67-4bb1-4d10-9a6c-ce901d1a0959.png" width="1280" />
  </figure>
  <p id="VAgj">Переходим в раздел &quot;Управленине данными&quot;.</p>
  <figure id="1PV8" class="m_column">
    <img src="https://img2.teletype.in/files/d2/f0/d2f0fd76-8e35-4ee4-a51d-14b83cbeebaf.png" width="1280" />
  </figure>
  <p id="QY1C">Выбираем &quot;Nintendo 3DS&quot;</p>
  <figure id="gbDE" class="m_column">
    <img src="https://img4.teletype.in/files/3f/48/3f48f7a6-e3f8-43c4-972d-1c251f0a2488.png" width="1280" />
  </figure>
  <p id="Nc92">Программы</p>
  <figure id="hqEa" class="m_column">
    <img src="https://img1.teletype.in/files/05/b1/05b1c194-9eea-411d-a848-3055fa858766.png" width="1280" />
  </figure>
  <p id="wsqz">В списке выбираем нужную программу и нажимаем удалить.</p>
  <figure id="9inY" class="m_column">
    <img src="https://img2.teletype.in/files/59/bb/59bb4274-e5df-4206-881e-2e8f806c530a.png" width="1280" />
  </figure>
  <figure id="iXXH" class="m_column">
    <img src="https://img1.teletype.in/files/cd/18/cd182bd7-a505-4e4a-ab93-4fa4cb5a6127.png" width="1280" />
  </figure>
  <p id="bVvT">Все, удалили игру.</p>
  <p id="oJ3K">Следующий, самый распространенный формат ромов - 3ds, который на прямую нельзя установить через FBI. Формат этот предназначен для эмулятора Citra, который я и не смотрел, пока он мне не очень интересен.</p>
  <p id="SNaf">Ромов игр в формате 3ds существенно больше, чтобы поиграть на консоли, придется конвертировать в cia.</p>
  <h3 id="fp0g">Конвертирование 3ds в cia</h3>
  <p id="oJjQ">Существует два способа конвертации,<strong> первый - внутри самой консоли</strong>, но для чего такие заморочки, если все равно нужно вынимать карту памяти? Этот способ ввиду его замороченности я рассматривать не буду.</p>
  <p id="99Bv">Второй способ - нормальный, конверация на компьютере через программу 3ds-to-cia, которая находится по этой вот ссылке <a href="https://github.com/drizzt/3ds-to-cia/releases/tag/v0.2.1" target="_blank">https://github.com/drizzt/3ds-to-cia/releases/tag/v0.2.1</a></p>
  <p id="hkbb">В простом случае, ничего, кроме копирования 3ds-рома  в папку <strong>/rom </strong>и запуска 3ds-to-cia.exe не нужно. В папке <strong>/cia</strong> появятся сконвертированные файлы. Как с ними поступить дальше - уже понятно. </p>
  <p id="gXoG">Но есть случаи, когда конвертер зацикливается и пишет, что нужен <strong>xorpad, </strong>что это - мне пока не понятно. </p>
  <p id="FEPZ">Если попадется какая-то интересная игра, которая потребует чуть больше углубиться в процесс конвертации, то инструкция будет дополнена.</p>
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <tt-tags id="1743">
      <tt-tag name="3ds">#3ds</tt-tag>
      <tt-tag name="2ds">#2ds</tt-tag>
      <tt-tag name="nintendo">#nintendo</tt-tag>
      <tt-tag name="old_games">#old_games</tt-tag>
      <tt-tag name="manuals">#manuals</tt-tag>
      <tt-tag name="retro_games">#retro_games</tt-tag>
      <tt-tag name="retro">#retro</tt-tag>
      <tt-tag name="games">#games</tt-tag>
      <tt-tag name="nintendo_ds">#nintendo_ds</tt-tag>
      <tt-tag name="nintendo_3ds">#nintendo_3ds</tt-tag>
      <tt-tag name="nintendo_2ds">#nintendo_2ds</tt-tag>
    </tt-tags>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@j3tboy/ngIfElse</guid><link>https://teletype.in/@j3tboy/ngIfElse?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy</link><comments>https://teletype.in/@j3tboy/ngIfElse?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy#comments</comments><dc:creator>j3tboy</dc:creator><title>Как использовать *ngIf совместно с else</title><pubDate>Thu, 25 May 2023 13:15:57 GMT</pubDate><description><![CDATA[Самая простая форма ]]></description><content:encoded><![CDATA[
  <p id="3Czc">Самая простая форма </p>
  <pre id="ezDj">&lt;div *ngIf=&quot;condition&quot;&gt;Контент отображается, если условие истинно&lt;/div&gt;</pre>
  <p id="Uwvk">Расширенный синтаксис </p>
  <pre id="YJ8z">&lt;ng-template [ngIf]=&quot;condition&quot;&gt;
 &lt;div&gt;Контент отображается, если условие истинно&lt;/div&gt;
&lt;/ng-template&gt;</pre>
  <p id="sEgk">Использование else</p>
  <pre id="urnI">&lt;div *ngIf=&quot;condition; else elseBlock&quot;&gt;
    Контент отображается, если условие истинно
&lt;/div&gt;

&lt;ng-template #elseBlock&gt;
    Контент отображается, если условие ложно
&lt;/ng-template&gt;</pre>
  <p id="V4Tc">Использование блоков then и else</p>
  <pre id="FwlV">&lt;div *ngIf=&quot;condition; then thenBlock else elseBlock&quot;&gt;
    Контент никогда не отображается
&lt;/div&gt;

&lt;ng-template #thenBlock&gt;
    Контент отображается, если условие истинно
&lt;/ng-template&gt;

&lt;ng-template #elseBlock&gt;
    Контент отображается, если условие ложно
&lt;/ng-template&gt;</pre>
  <p id="UdDq">Расширенный функционал</p>
  <pre id="KpGv">&lt;ng-template 
   [ngIf]=&quot;condition&quot; 
   [ngIfThen]=&quot;thenBlock&quot; 
   [ngIfElse]=&quot;elseBlock&quot;
&gt;
  Контент никогда не отображается
&lt;/ng-template&gt;

&lt;ng-template #thenBlock&gt;
  Контент отображается, если условие истинно
&lt;/ng-template&gt;

&lt;ng-template #elseBlock&gt;
  Контент отображается, если условие ложно
&lt;/ng-template&gt;</pre>
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="DVpJ"><a href="https://devsday.ru/blog/details/39571" target="_blank">https://devsday.ru/blog/details/39571</a></p>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@j3tboy/ngIf</guid><link>https://teletype.in/@j3tboy/ngIf?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy</link><comments>https://teletype.in/@j3tboy/ngIf?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy#comments</comments><dc:creator>j3tboy</dc:creator><title>Как использовать *ngIf с Async Pipe</title><pubDate>Thu, 25 May 2023 13:00:43 GMT</pubDate><description><![CDATA[Чтобы вывести два Observable значения в шаблоне с *ngIf нужно сделать следующее:]]></description><content:encoded><![CDATA[
  <p id="sRFx">Чтобы вывести два Observable значения в шаблоне с *ngIf нужно сделать следующее:</p>
  <pre id="S6FX">&lt;div *ngIf=&quot;product$ | async as product &amp;&amp; price$ | async as price&quot;&gt;
    &lt;b&gt;{{product}}&lt;/b&gt; and &lt;b&gt;{{price}}&lt;/b&gt;
&lt;/div&gt;</pre>
  <p id="s6h1">Лучшим решением будет скомбинировать два значения можно внутри компонента используя withLatestFrom, но обязательно нужно проверять на null  в шаблоне productPrice?.price.</p>
  <p id="o4j8"></p>
  <p id="9BWK">Самым лучшим вариантом комбинации двух Observable  значений будет испльзование вложенных *ngIf.</p>
  <pre id="D02U">&lt;ng-container *ngIf=&quot;product$ | async as product&quot;&gt;
  &lt;div *ngIf=&quot;price$ | async as price&quot;&gt;
    &lt;b&gt;{{product}}&lt;/b&gt; and &lt;b&gt;{{price}}&lt;/b&gt;
  &lt;/div&gt;
&lt;ng-container&gt;</pre>
  <p id="oxAC">При этом следует учесть, что запросы будут выполняться последовательно.</p>
  <p id="OGZU">Если требуется выполнить запросы одновременно, то уровней вложенности следует добавить.</p>
  <pre id="iBAZ">&lt;ng-container *ngIf=&quot;{ product: product$ | async, price: price$ | async } 
              as productPrice&quot;&gt;
  &lt;ng-container *ngIf=&quot;productPrice.product as product&quot;&gt;
    &lt;ng-container *ngIf=&quot;productPrice.price as price&quot;&gt;
      &lt;div&gt;&lt;b&gt;{{product}}&lt;/b&gt; and &lt;b&gt;{{price}}&lt;/b&gt;&lt;/div&gt;
    &lt;/ng-container&gt;
  &lt;/ng-container&gt;
&lt;/ng-container&gt;</pre>
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="ksC2"><a href="https://blog.angular-university.io/angular-reactive-templates/" target="_blank">https://blog.angular-university.io/angular-reactive-templates/</a></p>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@j3tboy/Input</guid><link>https://teletype.in/@j3tboy/Input?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy</link><comments>https://teletype.in/@j3tboy/Input?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy#comments</comments><dc:creator>j3tboy</dc:creator><title>Как обнаруживать изменения в @Input</title><pubDate>Mon, 27 Mar 2023 14:26:51 GMT</pubDate><description><![CDATA[Суть сводится к проверке объекта changes, получено ли изменение. Сhanges содержит текущее и предыдущее значение.]]></description><content:encoded><![CDATA[
  <h2 id="lMvJ">Способ №1 - <em>ngOnChanges</em></h2>
  <p id="D71o"></p>
  <pre id="AkDs" data-lang="javascript">export class SimpleComponent implements OnChanges {
@Input() id: number;

 ngOnChanges(changes: SimpleChanges) {
  if (!changes.id.firstChange) {
    console.log(changes.id.currentValue);
   }
  }
 }</pre>
  <p id="CNwl">Суть сводится к проверке объекта <strong>changes</strong>, получено ли изменение. Сhanges содержит текущее и предыдущее значение.</p>
  <p id="rxCg"> </p>
  <h2 id="sSG2">Способ №2 - использование set и get в параметре.</h2>
  <pre id="WRUB" data-lang="javascript">export class SimpleComponent implements OnChanges {
private _id: number;


@Input() 
set id(value: number) {
 this._id = value;
 }
 
get id(): number {
 return this._id;
 }
}</pre>
  <p id="Ic8h">Тут определяем функцию-сеттер для обнаружения изменений входной переменной. Сеттер всегда будет вызываться первым перед хуком жизненного цикла ngOnchanges.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@j3tboy/css-has</guid><link>https://teletype.in/@j3tboy/css-has?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy</link><comments>https://teletype.in/@j3tboy/css-has?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy#comments</comments><dc:creator>j3tboy</dc:creator><title>CSS псевдоклас :has - проверка наличия</title><pubDate>Thu, 09 Feb 2023 14:11:40 GMT</pubDate><description><![CDATA[Псевдокласс :has позволяет проверить, существует ли блок внутри родительского. Своеобразный if в CSS.]]></description><content:encoded><![CDATA[
  <p id="OSc7">Псевдокласс :has позволяет проверить, существует ли блок внутри родительского. Своеобразный if в CSS.</p>
  <p id="dYKG">Предположим, есть следующая структура:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="rH3Z">&lt;div class=&#x27;parent&#x27;&gt;<br />  &lt;div class = &#x27;child&#x27;&gt; &lt;/div&gt;<br />&lt;/div&gt;</p>
  </section>
  <p id="jPVH">Если chid имеется, то углы бордюра parent нужно скруглить, в противном случае - оставить 90 градусов.</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="EtaW">.parent<br />.child {<br />  border: 1px solid blck;	<br />  border-radius: 0;<br /> }</p>
    <p id="3jVM">.parent:has(.child) {<br />  border-radius: 16px;<br />}</p>
  </section>
  <p id="XiDh">Если нужно сделать наоборот, если нет child, то parent скруглить углы, то пишем</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Zbbg">.parent:not(:has(.child)) {<br />  border-radius: 16px;<br />}</p>
  </section>
  <p id="Q52e">Кроме этого, можно проверить, следует ли за parent child:</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="f5cd">.parent:has(+ child) {}</p>
  </section>
  <p id="OKeo">Можно выбрать прямой дочерний элемент:</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="8QJb">.parent:has(&gt; child) {}</p>
  </section>
  <p id="xJqY">Можно проверить наличие сразу нескольких элементов:</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="yIHL">.parent:has(.child, .sibling) {}</p>
  </section>
  <p id="er7O">Проверка отмеченного чек-бокса:</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="tcZS">.button-clear { <br />  display: none;<br /> }</p>
    <p id="zuMq"> .main-menu:has(input:checked) .button-clear { <br />   display: block;<br /> }</p>
  </section>
  <p id="FOfw">Также, можно обработать выбранное в селекторе значение:</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="OqQH">.some-prm {<br />    display: block;<br />}</p>
    <p id="XlC2">form:has(option[value=&quot;some&quot;]:checked) some-prm {<br />    display: block;<br />}</p>
  </section>
  <p id="LOzH">Проверить наличие нескольких дочерних элементов (количественные запросы) и сделать что-либо с каким-то из них:</p>
  <section style="background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="HsT7">.child {<br />    display: flex;<br />    gap: 1em;<br />}<br />  <br />.parent:has(.child:nth-last-child(n + 3)) .child:last-child {<br />    margin-left: auto;<br />}</p>
    <blockquote id="KUEB">последний элемент будет прижат к левому краю</blockquote>
  </section>
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="enkF"><a href="https://css-live.ru/css/psevdoklass-has-ne-tolko-roditelskij-selektor.html" target="_blank">https://css-live.ru/css/psevdoklass-has-ne-tolko-roditelskij-selektor.html</a></p>
    <p id="EdJ5"><a href="https://habr.com/ru/post/662355/" target="_blank">https://habr.com/ru/post/662355/</a></p>
    <p id="TztP"><a href="http://alistapart.com/article/quantity-queries-for-css/" target="_blank">http://alistapart.com/article/quantity-queries-for-css/</a></p>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@j3tboy/rxjs-cheat-sheet</guid><link>https://teletype.in/@j3tboy/rxjs-cheat-sheet?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy</link><comments>https://teletype.in/@j3tboy/rxjs-cheat-sheet?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy#comments</comments><dc:creator>j3tboy</dc:creator><title>RxJS - шпаргалка</title><pubDate>Mon, 19 Dec 2022 19:31:24 GMT</pubDate><tt:hashtag>rxjs</tt:hashtag><tt:hashtag>cheat_sheet</tt:hashtag><tt:hashtag>шпаргалка</tt:hashtag><description><![CDATA[Оператор слияния merge используется, когда мы хотим создать поток, который генерируется всякий раз, когда наблюдаемый источник (один из множества) выдает значение. ]]></description><content:encoded><![CDATA[
  <h2 id="OSJY">Операторы объединение Observable.</h2>
  <h3 id="lFct">merge - слияние</h3>
  <p id="QMrQ">Оператор слияния merge используется, когда мы хотим создать поток, который генерируется всякий раз, когда наблюдаемый источник (один из множества) выдает значение. </p>
  <p id="inWA">Например, если нужно отслеживать активность пользователя,чтобы выйти из системы или показать уведомление. Чтобы сделать это, нам нужно отслеживать активность пользователя, такую как клики, прокрутки, щелчки правой кнопкой мыши и тому подобное, и действовать, когда в течение определенных периодов времени не происходило никаких событий. Вот пример кода:</p>
  <pre id="PAn5" data-lang="javascript">const ACTIVE_EVENTS = [
  &#x27;click&#x27;, &#x27;scroll&#x27;, &#x27;contextmenu&#x27;, &#x27;dblclick&#x27;, &#x27;mousemove&#x27;,
];
// можно добавить любые события, для определения неактивности пользователя

merge(...ACTIVE_EVENTS
.map(event =&gt; fromEvent(document, event)))
.pipe(
bufferWhen(() =&gt; interval(10000)),
filter(events =&gt; events.length === 0),)
.subscribe(() =&gt; alert(&#x27;You have been inactive for ten seconds!&#x27;))</pre>
  <p id="2JAv">Тут создаются несколько потоков (используя FromEvent) для отслеживания различных событий браузера, которые могут указывать на активность пользователя, а затем объединяем их в один поток, чтобы действовать, когда какое-то время событий не было. Тип событий не важен, важен  факт, что событие произошло.</p>
  <p id="3wAC">Если важен сам факт наступления события, придется использовать “слияние” <strong>merge</strong>.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="twjS">bufferWhen(closingSelector: Observable): Observable</p>
    <p id="aVLu"><strong>bufferWhen -</strong> собирает данные из источника, наблюдаемого до тех пор, пока функция closingSelector не закроет буфер. </p>
    <p id="6w34"><strong>closingSelector </strong>- фабричная функция закрытия Observable, чтобы указать, когда закрывать, испускать и сбрасывать буфер.</p>
    <p id="wa6T">В данном случае, каждые 10000 мс происходит эммит значений.</p>
  </section>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="jzVg"><strong>Отличие buffer от bufferWhen</strong></p>
    <p id="QnBH">Оператор <strong>buffer </strong>принимает второй наблюдаемый объект в качестве аргумента и будет буферизовать значения из первого наблюдаемого объекта до тех пор, пока второй объект не будет передан. Затем buffer сбрасывается и начинает буферизацию снова, пока второй наблюдаемый объект не будет передан еще раз.</p>
    <p id="4xr9"><strong>bufferWhen </strong>похож на buffer, но вместо того, чтобы принимать наблюдаемый объект, он принимает функцию селектора (так называемый закрывающий селектор). </p>
    <p id="fZoN">Т.е. buffer эммитит значение, когда приходит значение наблюдаемого объекта, а bufferWen эммитит значение, когда выполняется функция.</p>
    <p id="QzY7">Есть еще:</p>
    <p id="1gWA"> -  <strong>bufferCount </strong>- позволяет задавать количество значений, которые нужно хранить в буфере, прежде чем они будут переданы.</p>
    <p id="hvx3"> - <strong>bufferTime </strong>- принимает количество миллисекунд для буферизации значений. По истечении времени буферизованные значения передаются, а буфер запускается снова.</p>
    <p id="HSAb"> - <strong>bufferToggle </strong>- принимает два аргумента: наблюдаемый объект, чтобы начать буферизацаию, и закрывающий селектор, чтобы остановить ее и выдать значения.</p>
  </section>
  <h3 id="aR7F">combineLatest</h3>
  <p id="h8qz">В некоторых случаях несколько отдельных событий запускают изменения в одной части пользовательского интерфейса. При этом нужны значения всех Observable (потоков) для вычисления <strong>конечного значения</strong>.</p>
  <p id="YZtI">Например, в зависимости от ввода значений в поля, с сервера приходят признаки обязательности для других полей и происходит перестройка интерфейса. </p>
  <p id="cqBl">combineLatest эммитит значение, когда какое-либо из отдельных потоков эмитит значение.</p>
  <pre id="WGfv" data-lang="javascript">// получаем данные от сервера - например, перечень
// динамических компонентов 
dynamicControls$ = this.controlsService.getDynamicControls();

formValue$ = combineLatest([
        this.form.valueChanges,
        this.dynamicControls$,
    ]).pipe(
        tap(([value]) =&gt; {
// тут происходит установка валидатора для полей.
            if (value.attachmentsRequired) {
                this.controls.attachments
                    .setValidators(Validators.required);
            } else {
                this.controls.attachments.clearValidators();
            }
        }),
        map(([value, controls]) =&gt; {
            const controlsValue = { ...value, ...controls };
            return controlsValue;
        }),
    );

</pre>
  <h3 id="VOGq">forkJoin </h3>
  <p id="FBRD">Если необходимо получить несколько наборов данных, которые извлекаются из разных API, нужно использовать <strong>forkJoin</strong>, чтобы дождаться, пока все данные будут доступны, и только после этого что-то делать в пользовательском интерфейсе.</p>
  <pre id="clPJ" data-lang="javascript">homePageData$ = forkJoin([
    this.userService.getUserInfo(),
    this.dataService.getData(),
    this.otherDataService.getOtherData(),
]).pipe(
    map(([userInfo, data, otherData]) =&gt; ({
        userInfo,
        data,
        otherData,
    })),
    catchError(error =&gt; of({/*error object*/})),
);</pre>
  <h3 id="Jnpm">pairwise</h3>
  <p id="I6HR">Объединяет предыдущее и текущее значение потока.</p>
  <p id="Gzsc">Например, когда нужно в предварительно заполненной форме проверить изменения.</p>
  <p id="DdVY">Для простых случаев можно использовать состояние формы <strong>dirty</strong>, но если необходимо учитывать не только факт изменения в полях, а еще чтобы старое значение не совпадало с новым, то можно использовать pairwaise.</p>
  <pre id="aSiv" data-lang="javascript">disabled$ = this.form.valueChanges.pipe(
    pairwise(),
    map(([prev, current]) =&gt; {
        return this.utilitiesService.isEqual(prev, currentnged
    }),
);</pre>
  <h3 id="aVnW">withLatestFrom - &quot;с последним из&quot;</h3>
  <p id="cadI">Объединяет два потока, причем из потока <strong>withLatestFrom </strong>эммитит только последнее значение.</p>
  <p id="FkvL">Когда основной поток выкидывает значение, то он просит <strong>withLatestFrom </strong>дать последнее значение которое у него было.</p>
  <pre id="hqo0" data-lang="javascript">this.authService.login(credentials).pipe(
    withLatestFrom(
      this.route.queryParamMap.pipe(startWith(new Map())),
    ),
).subscribe(([, params]) =&gt; {
    if (params.get(&#x27;redirectUrl&#x27;)) {
        const navUrl = params.get(&#x27;redirectUrl&#x27;) ?? &#x27;/home&#x27;;
        this.router.navigateByUrl(decodeURIComponent(navUrl));
    }
});</pre>
  <p id="Xlc0">Необходимо перенаправить со страницы при успешном входе в систему,<strong> но только </strong>при наличии параметра запроса “redirect_url”. Мы можем взять это значение из наблюдаемого параметра queryParamMap, но мы не хотим запускать перенаправление, когда параметр запроса изменяется по какой-либо причине, только после завершения успешного HTTP-вызова login.</p>
  <p id="mmaI">Действие не будет выполнено при изменении параметров запроса, а только при успешном завершении вызова login.</p>
  <h3 id="JAga">debounceTime, throttleTime, auditTime</h3>
  <p id="GXbK"><strong>debounceTime -</strong> эмитит значение из Observable, только после того, как прошел определенный промежуток времени. Использовать, если нужно реализовать автокомплит или упреждаюдищий ввод ( typeahead ).</p>
  <p id="EI40"><strong>throttleTime -</strong> эмитит значение из Observable, затем игнорирует последующие значения источника в течение миллисекунд, затем повторяет этот процесс. Использовать, если нужно реализовать ограничение частоты кликов, обработку двойного клика.</p>
  <p id="2wrB"><strong>auditTime </strong>- эмитит самое последнее значение за указанный период времени.</p>
  <h3 id="FcaY">retry</h3>
  <p id="RrSN">Простейший случай:</p>
  <pre id="sLWF" data-lang="javascript">responseFromServer$.pipe(
    retry(3), // делаем три попытки
); // после 3 неудачных попыток обрабатываем ошибку.</pre>
  <p id="P8BW">Ожидание нажатия кнопки с оператором повторов:</p>
  <pre id="y2q9" data-lang="javascript">responseFromServer$.pipe(
    retry({
        count: 3, // можем указать опциональное количество
                  // сколько раз пользователь может 
                  // повторить попытку
        delay: () =&gt; fromEvent(
              document.querySelector(&#x27;#retryBtn&#x27;),
              &#x27;click&#x27;,
        ), // ожидаем нажатия кнопки
    }),
);</pre>
  <section style="background-color:hsl(hsl(323, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="e93E"><a href="https://dev.to/this-is-learning/understanding-rxjs-use-cases-part-ii-51ll" target="_blank">https://dev.to/this-is-learning/understanding-rxjs-use-cases-part-ii-51ll</a> оригинал статьи.</p>
  </section>
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <tt-tags id="mhyY">
      <tt-tag name="rxjs">#rxjs</tt-tag>
      <tt-tag name="cheat_sheet">#cheat_sheet</tt-tag>
      <tt-tag name="шпаргалка">#шпаргалка</tt-tag>
    </tt-tags>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@j3tboy/The_Chronicles_of_Riddick_widescreen_manual</guid><link>https://teletype.in/@j3tboy/The_Chronicles_of_Riddick_widescreen_manual?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy</link><comments>https://teletype.in/@j3tboy/The_Chronicles_of_Riddick_widescreen_manual?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=j3tboy#comments</comments><dc:creator>j3tboy</dc:creator><title>The Chronicles of Riddick: Escape from Butcher Bay - как настроить для игры на широкоформатном мониторе</title><pubDate>Sun, 11 Dec 2022 21:15:51 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/61/9d/619dcd2c-cd85-4d43-b23f-f27ff1ced6f6.png"></media:content><tt:hashtag>the_chronicles_of_riddick</tt:hashtag><tt:hashtag>escape_from_butcher_bay</tt:hashtag><tt:hashtag>widescreen</tt:hashtag><tt:hashtag>old_games</tt:hashtag><tt:hashtag>manuals</tt:hashtag><tt:hashtag>retro_games</tt:hashtag><tt:hashtag>retro</tt:hashtag><tt:hashtag>games</tt:hashtag><description><![CDATA[<img src="https://img4.teletype.in/files/30/f5/30f56869-4ecb-4663-85a3-da311163adfb.png"></img>Это краткая инструкция по настройке стареньких игр для воспроизведения на широкоформатных мониторах.]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="DKAy">Это краткая инструкция по настройке стареньких игр для воспроизведения на широкоформатных мониторах.</p>
  </section>
  <h2 id="GLB5">В чем проблема?</h2>
  <p id="sUoE">Нельзя просто взять и запустить игру 2004 года на широкоформатном мониторе widescreen. Придется чуть настроить.  Без настроек изображение выводиться просто огромное, как будто видишь одним глазом, левый верхний угол экрана до середины.</p>
  <p id="aiqq">Для примера, на рисунке 1 отображется игра без настройки.</p>
  <figure id="Ggdt" class="m_column">
    <img src="https://img4.teletype.in/files/30/f5/30f56869-4ecb-4663-85a3-da311163adfb.png" width="2004" />
    <figcaption>Рисунок 1 - без настроек и тут видно, что на экране уместилось дай бог четверть картинки, что вообще никак не играбельно. </figcaption>
  </figure>
  <p id="WvhB">А на рисунке 2 - уже с настройкой. </p>
  <figure id="UtDR" class="m_column">
    <img src="https://img4.teletype.in/files/b4/21/b4214f95-fb60-454d-aa98-484e21c8eaa5.png" width="1526" />
    <figcaption>Рисунок 2 - настройка выполнена</figcaption>
  </figure>
  <p id="NT6e">Добиться пропорционального вида так и не получилось, но в принципе, уже играть хоть как-то можно. </p>
  <h3 id="VMYs">Шаг №1</h3>
  <p id="w6gL">1.1 Переходим в папку с игрой, находим riddick.exe и правой кнопкой мыши открываем свойства, переходим на вкладку &quot;Совместимость.&quot;</p>
  <p id="rdhO">1.2 Установить &quot;Режим совместимости&quot; - Windows XP (Service Pack 3).</p>
  <p id="3XLJ">1.3 Установить галочку &quot;Отключить оптимизацию во весь экран&quot;.</p>
  <p id="vQWk">1.4 Нажать кнопку &quot;Изменить параметры высокого DPI&quot;.</p>
  <p id="03uw">1.5 Установить галочку &quot;Переопределить режим масштабирования высокого разрешения&quot; - &quot;Масштабирование выполняется&quot; - выбрать &quot;Приложение&quot;.</p>
  <p id="8gnW">1.6 СОХРАНИТЬ.</p>
  <p id="5RxB">На рисунке 3 отмечены основные моменты шага 1.</p>
  <p id="wZQX"></p>
  <figure id="Y7jv" class="m_column">
    <img src="https://img4.teletype.in/files/3b/1c/3b1c966c-a152-4b8c-a9c2-db716bbafc0c.png" width="1434" />
    <figcaption>Рисунок 3 - основные настройки шага 1.</figcaption>
  </figure>
  <h3 id="pfq0">Шаг №2</h3>
  <p id="BYUh">2.1 Запускаем игру и переходим в настройки монитора.</p>
  <p id="Kd7A">2.2. Устаналвиваем разрешение 1920x1440.</p>
  <p id="gugd">2.3 Устанавливаем соотношение сторон (aspect ration) 4: 3 -&gt;2.35.</p>
  <p id="DZcS">2.4 Применяем настройки и начинаем играть.</p>
  <p id="4KQG"></p>
  <section style="background-color:hsl(hsl(323, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="pSRu">Да, еще интересный момент - я не смог нормально сделать скрины или захватить видео геймплея. Рисунки 1 и 2 - это мои скрины, но сделаные через сальто.</p>
  </section>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="SjWA">Ссылка на исходник мануала - <a href="https://www.nexusmods.com/chroniclesofriddick/mods/1" target="_blank">https://www.nexusmods.com/chroniclesofriddick/mods/1</a></p>
  </section>
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <tt-tags id="Ieh1">
      <tt-tag name="the_chronicles_of_riddick">#the_chronicles_of_riddick</tt-tag>
    </tt-tags>
    <tt-tags id="hFFJ">
      <tt-tag name="escape_from_butcher_bay">#escape_from_butcher_bay</tt-tag>
    </tt-tags>
    <tt-tags id="kTzW">
      <tt-tag name="widescreen">#widescreen</tt-tag>
      <tt-tag name="old_games">#old_games</tt-tag>
      <tt-tag name="manuals">#manuals</tt-tag>
      <tt-tag name="retro_games">#retro_games</tt-tag>
      <tt-tag name="retro">#retro</tt-tag>
      <tt-tag name="games">#games</tt-tag>
    </tt-tags>
  </section>

]]></content:encoded></item></channel></rss>