Предстоящие изменения в заголовке: подготовка тем и плагинов

Недавно мы работали над обновлением заголовка Discourse: переход от устаревшей системы рендеринга «виджетов» к современным компонентам Glimmer. Это изменение уже доступно в ядре Discourse и управляется настройкой сайта glimmer header mode.

:timer_clock: Примерный график

(очень приблизительные оценки — могут измениться в любую сторону)

Q1 2024:

  • :white_check_mark: реализация в ядре завершена и включена на Meta

  • :white_check_mark: опубликованы рекомендации по обновлению; включены сообщения об устаревании в консоли

  • :white_check_mark: начата работа по обновлению всех официальных и сторонних плагинов/тем

Q2 2024:

  • :white_check_mark: начало включения новой реализации заголовка по умолчанию

  • :white_check_mark: официальные и сторонние темы/плагины готовы к обновлению

  • :white_check_mark: сообщения об устаревании начинают вызывать предупреждающий баннер для администраторов при наличии оставшихся проблем

Q3 2024:

  • :white_check_mark: опубликована тема с объявлением для широкого освещения: Preparing your community for behind-the-scenes header changes

  • :white_check_mark: неделя с 5 августа 2024 года (v3.4.0.beta1): новый заголовок включён по умолчанию для всех сайтов. Администраторы всё ещё смогут переключиться на старый заголовок, изменив настройку сайта glimmer header mode.

  • :white_check_mark: неделя с 2 сентября 2024 года: окончательное удаление флага функции и устаревшего кода

:eyes: Что это значит для вас?

Если ваш плагин или тема использует какие-либо API «виджетов» для кастомизации заголовка, их необходимо обновить для совместимости с новым заголовком.

:person_tipping_hand: Как попробовать новый заголовок?

В последней версии Discourse новый заголовок автоматически включается, когда все ваши темы и плагины совместимы.

Если ваши темы/плагины не совместимы, будет использоваться старый заголовок, а в консоли вместе с существующими сообщениями об устаревании будет выведено предупреждение. Также администраторам будет показан предупреждающий баннер в интерфейсе.

В маловероятном случае, если эта автоматическая система не сработает как ожидалось, вы можете временно переопределить этот «автоматический флаг функции» через настройку сайта glimmer header mode. Если вы это сделаете, пожалуйста, сообщите нам причину в этой теме.

:technologist: Нужно ли мне обновлять мой плагин/тему?

Чтобы определить, требует ли ваша кастомизация обновления, проверьте, использует ли она decorateWidget, changeWidgetSetting, reopenWidget или attachWidgetAction для любого из следующих виджетов:

  • header
  • site-header
  • header-contents
  • header-buttons
  • user-status-bubble
  • sidebar-toggle
  • header-icons
  • header-topic-info
  • header-notifications
  • home-logo
  • user-dropdown

или использует один из следующих методов API плагинов:

  • addToHeaderIcons
  • addHeaderPanel

Все эти действия теперь будут вызывать вывод сообщений об устаревании в консоль. ID устаревания:

  • discourse.add-header-panel
  • discourse.header-widget-overrides

:warning: Если в вашем экземпляре используется более одной темы, обязательно проверьте все из них.

Уведомление администраторам

По состоянию на 20 июня 2024 года мы включили уведомление администраторам для вышеуказанных устареваний.

Если ваш экземпляр был развёрнут после этой даты и текущие плагины, тема или компоненты темы вашего экземпляра вызывают одно из предупреждений об устаревании, следующее сообщение будет отображаться только для администраторов*:

Это сообщение предназначено только для того, чтобы предупредить администраторов о необходимости скорого принятия мер по модернизации затронутых кастомизаций: старые кастомизации всё ещё будут работать, пока мы не удалим устаревшую кодовую базу.

:twisted_rightwards_arrows: Чем заменить?

Каждая тема/плагин индивидуальна, но вот рекомендации для наиболее распространённых случаев использования:

addToHeaderIcons

:information_source: Для пользовательских иконок заголовка мы рекомендуем удалить ваш код и установить официальный компонент темы Custom Header Links (Icons). Если это не отвечает вашим требованиям, см. ниже информацию о необходимых изменениях в коде:

API плагинов addToHeaderIcons устарел в пользу нового API headerIcons. Он предназначен для добавления, удаления или изменения порядка иконок в заголовке. Требуется передача компонента.

Компонент можно передать следующим образом:

До После
api.addToHeaderIcons(“widget-foo”) api.headerIcons.add(“foo”, FooIcon)
api.decorateWidget(“header-icons:before”, () => return helper.h(“div”, “widget-foo”)) api.headerIcons.add(“foo”, FooIcon, { before: “search” })
api.decorateWidget(“header-icons:after”, () => return helper.h(“div”, “widget-foo”)) api.headerIcons.add(“foo”, FooComponent, { after: “search” })

В этом примере используется формат шаблонов (gjs) в Ember для определения компонента внутри и передачи его в API headerButtons.add:

// .../discourse/api-initializers/add-my-button.gjs

import DButton from "discourse/components/d-button";
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.0", (api) => {
  api.headerIcons.add("some-unique-name", <template>
    <li><DButton class="icon btn-flat" @href="/u" @icon="address-book" /></li>
  </template>);
});

Или для выпадающего меню можно использовать <DMenu вместо <DButton:

import DButton from "discourse/components/d-button";
import { apiInitializer } from "discourse/lib/api";
import DMenu from "float-kit/components/d-menu";

export default apiInitializer("1.0", (api) => {
  api.headerIcons.add("some-unique-name", <template>
    <li>
      <DMenu class="icon btn-flat" @icon="address-book">
        <DButton @translatedLabel="Пользователь 1" @href="/u/user1" />
        <DButton @translatedLabel="Пользователь 2" @href="/u/user2" />
        <DButton @translatedLabel="Пользователь 3" @href="/u/user3" />
      </DMenu>
    </li>
  </template>);
});

Примеры коммитов обновления:

decorateWidget("header-buttons:*")

:information_source: Для пользовательских ссылок в заголовке мы рекомендуем удалить ваш код и установить официальный компонент темы Custom Header Links. Если это не отвечает вашим требованиям, см. ниже информацию о необходимых изменениях в коде:

Виджет header-buttons устарел, и мы внедрили API плагинов headerButtons. Он предназначен для добавления, удаления или изменения порядка кнопок в заголовке. Требуется передача компонента.

До После
api.decorateWidget(“header-buttons:before”) api.headerButtons(“button-name”, ButtonComponent, { before: “auth” })
api.decorateWidget(“header-buttons:after”) api.headerButtons(“button-name”, ButtonComponent, { after: “auth” })

changeWidgetSetting(...) для виджетов заголовка

:information_source: Наиболее распространённые случаи использования changeWidgetSetting можно реализовать с помощью следующих компонентов темы:

Если они не подходят для вашего случая использования, читайте дальше…

Некоторые кастомизации виджетов заголовка использовали API changeWidgetSetting.

Хотя прямого аналога для кастомизаций, подобных вышеуказанным, нет из-за особенностей работы полей компонентов Glimmer, мы внедрили новый API плагинов в версии Discourse 3.3.0.beta3 для обработки некоторых из этих случаев.

registerValueTransformer можно использовать для переопределения значений, помеченных в исходном коде как переопределяемые; это аналогично тому, как работают выходы плагинов (plugin outlets).

Мы уже добавили два трансформатора для случаев использования, которые часто встречаются в нашей кодовой базе:

  • home-logo-href: можно использовать для переопределения URL в ссылке логотипа главной страницы. См. раздел home-logo ниже для примеров.

  • header-notifications-avatar-size: можно использовать для изменения размера изображения аватара пользователя в заголовке. Пример:

Код ниже:

api.changeWidgetSetting(
  "header-notifications",
  "avatarSize",
  settings.header_avatars_size
);

Будет преобразован в:

api.registerValueTransformer(
  "header-notifications-avatar-size",
  () => settings.header_avatars_size
);

Эти трансформаторы необходимо добавить в исходный код Discourse. Если вам нужен другой, пожалуйста, сообщите нам, опубликовав свой случай использования ниже.

Дополнительные сведения о новых API трансформаторов значений можно найти здесь.

home-logo

Мы внедрили выход плагина home-logo вместо декораций виджетов home-logo:before или home-logo:after. Вы можете использовать автоматическое именование __before и __after в вашем файле коннектора, чтобы указать, где должно располагаться ваше пользовательское содержимое.

Дополнительные сведения об именовании файлов коннекторов before/after можно найти здесь.

До После
api.decorateWidget(“home-logo:before”) Переместить содержимое в /connectors/home-logo__before
api.decorateWidget(“header-buttons:after”) Переместить содержимое в /connectors/home-logo__after)

Изменение URL ссылки логотипа главной страницы:

Очень часто возникает необходимость изменить URL, на который ведёт ссылка home-logo. Для решения этой проблемы мы внедрили трансформатор значений home-logo-href. Примеры:

  • для изменения ссылки на статический URL

    api.registerValueTransformer("home-logo-href", () => "https://example.com");
    
  • для возврата динамического URL на основе текущего пользователя

    api.registerValueTransformer("home-logo-href", () => {
      const currentUser = api.getCurrentUser();
      return `https://example.com/${currentUser.username}`;
    });
    
  • для возврата URL на основе настройки компонента темы

    api.registerValueTransformer("home-logo-href", () => {
      return settings.example_logo_url_setting;
    });
    

:sos: А как насчет других кастомизаций?

Если вашу кастомизацию невозможно реализовать с помощью CSS, PluginOutlets или новых API, которые мы внедрили, пожалуйста, сообщите нам, создав новую тему в канале Development для обсуждения.

:sparkles: Как обновить тему/плагин для поддержки как старого, так и нового заголовка?

Все новые API и выходы плагинов, перечисленные в этом документе, поддерживаются как в новом, так и в старом заголовке. Поэтому вам нужно внести только одно обновление в вашу тему/плагин сейчас, и пользователи будут готовы к переходу.

Но как мне определить FooIcon?

В плагине я попытался создать /assets/javascripts/discourse/components/server-link.js (как для других компонентов, которые я использую в hbs-файле):

import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";

export default Component.extend({
// что-то должно быть здесь?
});

И assets/javascripts/discourse/templates/components/server-link.hbs с содержимым:
this is a link (я предполагаю, что смогу сделать это ссылкой, если у меня получится запустить этот “Hello, world”)

В приведённом выше примере есть const IconWithDropdown = ..., но где это должно находиться? Я пытался поместить это в инициализатор (туда, где был api.decorateWidget), но, насколько я могу судить, это не выглядит ни валидным JavaScript, ни чем-то понятным Ember.

Раньше у меня был массив headerlinks, и я делал так:

        headerLinks.push(
          h(
            `li.headerLink.no-servers`,
            h("a", anchorAttributes, I18n.t("pfaffmanager.no_servers_title"))
          )
        );

чтобы добавить нужные ссылки. Я думаю, что если мне удастся заставить работать:

      api.headerIcons.add("foo", ServerLink, { before: "search" });

то я смогу просто поместить это в цикл, который формировал тот массив.

Ого. Получается, глимпер-компоненты размещаются в assets/javascripts/discourse/component, а эмбер-компоненты — в assets/javascripts/discourse/components?!?!

Теперь у меня есть файл server-link.gjs:

import Component from "@ember/component";
export default class ServerLink extends Component {
  // Обязательный аргумент для URL
  url = null;
  // Необязательный аргумент для текста ссылки
  text = 'asdf';
  click() {
    console.log('ServerLink clicked!',this);

  }
  // Шаблон компонента
  <template>
    {{log "my template" this}}
    LINK!
    <a href={{this.url}}>{{this.text}}</a>
  </template>
}

А в инициализаторе я использую это:

      api.headerIcons.add("foo", ServerLink, { param: "url, yo", before: "search" });

Теперь в шапке что-то отображается.

Но как передать данные в ServerLink? Мне нужно вызывать его несколько раз с разными URL и разным текстом для клика. Я не могу увидеть данные из того объекта {} внутри компонента.

К тому же, вы не можете просто писать JavaScript перед <template>, так как мой console.log("") не будет распознан!

Я также пробовал делать так:

      const x = new ServerLink({
        url: "mylink",
        text: "my-text",
        name: 'Bob',
        message: 'Generated from JavaScript',
      });

а затем передавать x вместо ServerLink, но это тоже не помогло.

Вы имеете в виду, что хотите несколько кнопок в заголовках с разными иконками/текстом/URL или одну и ту же кнопку, но в зависимости от контекста текст/URL могут меняться?

Да, вы находитесь внутри класса — там вы можете объявлять переменные, функции или шаблоны!

Да. Ссылки меняются для разных пользователей. Старый код ссылался через массив servers и добавлял их в этот массив:

            headerLinks.push(
              h(
                `li.headerLink${deviceClass}${newClass}`,
                h("a", anchorAttributes, linkText)
              )
            );

А затем делал следующее:

      // api.decorateWidget("header-buttons:before", (helper) => {
      //   return helper.h("ul.pfaffmanager-header-links", headerLinks);
      // });

Таким образом, у меня было до 3 ссылок, которые добавлялись в заголовок, каждая из которых вела на отдельный URL сервера.

Ага. Теперь я понял.

Нет, не переживайте — соглашение всё ещё /components/ :sweat_smile:

(Технически вы можете определять и передавать gjs-компоненты как угодно, поэтому можете выбрать любое имя директории. Но мы придерживаемся /components/.)

Да, это справедливый вопрос — я займусь написанием документации «с нуля» о том, как добавлять иконки в заголовок, чтобы у нас был более понятный ориентир.

Тем временем, возможно, вам стоит посмотреть на обновление discourse-icon-header-links для вдохновения. Круто в использовании GJS то, что вы можете определять компоненты где угодно, и они получают доступ к переменным в локальной области видимости.

Так что, если вы переименуете свой инициализатор в .gjs, вы сможете делать вот что:

servers.forEach((server) => {
  api.headerIcons.add(`server-${server.id}`, <template>
    <li><DButton @translatedLabel={{server.name}} @icon="server" /></li>
  </template>);
});

Или вы можете определить компонент раньше в том же файле и использовать его так:

class ServerButton extends Component {
  get icon(){
    // какая-то логика для выбора иконки
  }
  <template>
    <li><DButton @translatedLabel={{@server.name}} @icon={{this.icon}} /></li>
  </template>
}

...

servers.forEach((server) => {
  api.headerIcons.add(`server-${server.id}`, <template>
    <ServerButton @server={{server}} />
  </template>);
});

Или вы можете перенести итерацию внутрь шаблона (полезно, если список серверов — это TrackedArray, который может изменяться во время выполнения!):

api.headerIcons.add("server-buttons", <template>  
  {{#each servers as |server|}}
    <ServerButton @server={{server}} />
  {{/each}}
</template>);

О. Ура. Я думал, что пробовал использовать components, и это не сработало.

Спасибо! Думаю, я смогу заставить это работать. Ссылка на заголовочные ссылки очень помогла. Я почти уверен, что когда я писал свой код, у меня хватило ума посмотреть на тот самый компонент, чтобы разобраться в этом тогда.

Видим проблеск надежды!

Привет @david и @Arkshine! У меня получилось!

Вааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааааа

Я обновил первый пост, добавив полностью рабочие примеры gjs, а также включил ссылку на актуальную документацию Ember. Как тебе это выглядит, @pfaffman? Есть ли ещё что-то, что, по твоему мнению, стоит добавить?

Это лучше, так как есть рабочий пример. Но я правильно понимаю, что существуют компоненты Ember и компоненты Glimmer? И если это так, то, думаю, стоит указать, что требуется компонент Glimmer?

И, возможно, добавить ссылку на документацию по Glimmer, объясняющую, как они работают?

Кажется, можно создавать встроенные компоненты, как в вашем примере, и ещё один тип, где компонент присваивается переменной в том же файле или размещается в отдельном файле в директории components, а затем подключается? Думаю, для этой темы всё это может быть слишком объёмно, но мне бы очень хотелось увидеть отдельную тему, посвящённую этому.

Они полностью взаимозаменяемы — вы можете использовать классический компонент Ember или компонент Glimmer. И для любого из них вы можете выбрать написание в старом формате .js/.hbs или в новом формате .gjs.

Я посмотрю, смогу ли добавить ссылки на документацию Ember :+1:

:mega: Сегодня мы объединили это изменение, которое автоматически включит новую реализацию заголовка для сайтов с совместимыми темами/плагинами.

Если ваши темы/плагины не совместимы, будет использоваться устаревший заголовок, и в консоль будет выведено предупреждение вместе с существующими сообщениями об устаревании. В ближайшем будущем это предупреждение в консоли будет заменено на баннер с предупреждением в интерфейсе.

В маловероятном случае, если это автоматическое изменение вызовет проблемы, вы можете временно переопределить этот «автоматический фича-флаг» через настройку сайта glimmer header mode. Если вы это сделаете, пожалуйста, сообщите причину в этой теме.

Я не планировал вносить какие-либо изменения, но уведомления об устаревании говорят об обратном.

Так что есть выбор, и, возможно, есть простой способ просто сохранить статус-кво?

или

Чего мне не хватает, если я решу сохранить старый заголовок? Я не понимаю, что означает новый. Я вижу настройки групп, индивидуальная настройка для разных групп кажется интересной, но что именно можно настроить?

Вот что я нашел сегодня:

Я не гуру и не мастер в этих изменениях; они требуют времени, и я не делаю их достаточно часто, чтобы действительно захотеть освоить приемы, которые пользователи здесь, кажется, легко понимают и знают.

Я немного неохотно вынужден заниматься этим в принципе, но прежде чем я начну кричать, как старый человек, у которого закончился пудинг, я хотел бы знать: что, почему и куда это ведет?

Я занимаюсь этим профессионально, и даже я считаю, что эти вещи с JavaScript далеко не просты.

Я тоже старый человек, и я понимаю твою боль.

К сожалению, это просто прогресс. Это обновление Ember сломало множество вещей, и это ещё не конец.

Ты “заказывал” это, когда делал эту кастомизацию. Я уверен, что за последние пять лет ты сменил телефон или ноутбук.

Если бы я был на твоём месте (а ты был бы на моём, без постоянной работы в Discourse), я бы написал в Marketplace. Если бы я был собой, я бы, скорее всего, не отвечал за сумму меньше 300 долларов, но есть разумная вероятность, что кто-то другой согласится за 100 или 200 долларов. Я предполагаю, что это больше не сломается ещё лет пять или даже дольше.

Я думаю, что селектор тем с гамбургер-менем можно убрать и использовать боковую панель.

Приятный честный ответ, спасибо, но материала для работы немного, возможно, будет что-то ещё (надеюсь)

Я даже не знал, что мы имеем дело с Java здесь :man_shrugging:

Не хочу, чтобы кто-то забрал твоё пудинг тоже :face_with_hand_over_mouth:

Конечно, но какова желаемая цель? Это программное обеспечение затрагивает столько областей, что я задаюсь вопросом: кто видит конечную точку?

Разве это нужно просто из-за обновления Ember?

Я тоже не знаю, зачем вообще делали обновление Ember, но если работает, зачем чинить? Уверен, есть длинное и глубокое объяснение, которое ведёт к будущему, но разве нет истинной vision, которую можно было бы разделить?

Я посещаю другие форумы, использующие очень устаревшее программное обеспечение. Лично я считаю Discourse намного лучше любого из них, но они, кажется, не страдают от сравнения. У них те же проблемы с ростом. По моему мнению, это больше вопрос личности, чем программного обеспечения. Слишком много старых участников, которые потеряли свой «пудинг». Я задаюсь вопросом: есть ли будущее IoT, которое буквально сделает все эти форумы устаревшими, где они вообще не будут работать, и знает ли об этом Discourse, готовясь к этому?

Вот ещё немного той честности, которую ты предлагаешь :grin: действительно верно, и я был более готов учиться, более амбициозен, чувствовал, что это стоит того. С тех пор меня били, сбивали с ног и оставляли умирать.

Ладно, ты на пари, я принимаю вызов. А так как ты уже проиграл, помоги мне с этим, и мы станем друзьями.

Тогда ты, скорее всего, бросил бы это дело очень давно. Фраза «меня били, сбивали с ног и оставляли умирать» была немного эвфемизмом. Остался только я за рулём, полагаю, кто-то другой где-то в панели пытается починить гипердвигатель. Не знаю, так как я редко общаюсь с другими. У нас нет финансирования. Мы (FULL30) были заблокированы в социальных сетях, а также в Discourse. Интересно, сколько других платящих клиентов Discourse добровольно отпустил или сколько других были признаны настолько оскорбительными в своих убеждениях, что Discourse публично выступил против них?

Тем не менее, говоря правду, я не обижаюсь. Живи и дай жить другим. Я знаю, что будущее наступает, но не знаю, почему я всё ещё здесь и продолжаю пытаться. Но я продолжаю, так что буду продолжать, как в АА: только на сегодня :hugs:

Но когда я её использовал, это было очень модно :expressionless:

Боковую панель (здесь) можно закрыть с помощью меню-гамбургера, функционально особой разницы нет: открывается и закрывается окно навигации, но мою нельзя легко сохранить?

Да, я бы с радостью и предпочёл бы заплатить кому-то, чтобы тот привёл мой кастомизированный код в порядок и заставил всё работать красиво. Я с удовольствием заплачу, мне нравится нанимать людей, делиться богатством. Когда вырасту, хочу стать филантропом, но сегодня мне нужен филантроп :innocent: и ещё раз благодарю за любую помощь, которую другие могут предложить.

Другой способ решить проблему — обратиться за помощью к сообществу: прекратите вносить изменения, создайте новую тему, в которой поделитесь своим кодом, и попросите о помощи. Недавно я сам получил много помощи в подобных ситуациях.

К сожалению, нет. Возможность остаться на «старом заголовке» — это лишь временная мера в переходный период. Вскоре новый заголовок станет единственным вариантом.

Да! Мы всегда рады помочь с вопросами в Development. Кроме того, публикация кода и решений создаёт полезный ресурс для других.

Фух, моё сообщество больше озабочено другими вопросами.

Конечно, я мог бы поделиться здесь, но тогда получится наоборот: какой программист найдёт интерес в том, чтобы помочь нам?

Ирония в том, что программирование может стать оружием будущего, способным причинить гораздо больше смерти и разрушений, но я отвлекся.

Очень хорошо, но что это именно означает для меня? Создать одну группу пользователей, публичную и для тех, кто не авторизован?

Эти настройки групп, как мне кажется, основаны на уровнях доверия, а не на реальных различных группах, вроде охотничьей или рыболовной?

Сначала мне нужно понять цель и определить, где мои усилия в одиночку принесут наибольшую отдачу, сэкономив время и сохранив уникальный стиль моего форума.


Я не хочу уводить чужую ветку в сторону; если решат, что это должна быть отдельная ветка, я не против.

Но как может возникнуть по-настоящему сплочённая связь, когда люди чувствуют необходимость удалить что-то, что их оскорбляет?

Требуется терпение, чтобы понять других. Ссылка была удалена: логотип отсутствовал после публикации, но не во время неё. Это ещё одна проблема с заголовком, которую нужно обсудить?

Это был пост на моём форуме, написанный человеком, которому, как я полагаю, уже за 80. Я мог бы спросить наверняка, но он отказывается со мной говорить. Должен ли я его порицать, банить или игнорировать?

Нет, почему? Потому что есть лучший способ, но он означает смириться с другими и их взглядами. Я нахожу хороших людей в плохих местах, хороших людей, которые выглядят плохо, и наоборот — в обоих случаях.

Точно. Я только что нашёл ошибки, хочу их исправить, но не понимаю корневую причину, кроме как того, что будущее движется вперёд. Нам нужен новый заголовок, хорошо, но какой правильный путь выбрать для настройки моего сайта: простая настройка или полная коррекция курса?

Обсуждаем ли мы, что нужно проработать только эти три области?

У меня смешанное использование компонентов: начал с нуля, затем понял, что они могут быть полезны. Я никогда не использовал только компоненты, у меня получается смесь.

Вот моя тема, насколько она имеет значение, без компонентов:
discourse-full30-ii.zip (10.1 KB)
Я могу опубликовать и их тоже; некоторые модальные окна уже не работают с недавнего времени.