Jump to content

Библиотеки и фреймворки.


s0rr0w
 Share

Recommended Posts

Не вижу взаимосвязи между мышлением кодера и фреймвёрком. Юзать чужой код и соображать головой что делаешь - можно.

Хотите, я на вашем примере докажу, что фреймворки изменяют мышление?

Резюме: считаю что истинный смысл топа - флуд и кичь.

Истинный смысл топа - показать другое решение.

Link to comment
Share on other sites

  • Replies 55
  • Created
  • Last Reply

Top Posters In This Topic

Будьте так любезны

Есть таблица. В таблице 3 колонки и несколько строк. В первой колонке каждой строки стоит кнопка. При нажатии на кнопку под строкой появляется контейнер, в котором будет находиться произвольный контент, но нам достаточно того, чтобы там находился ID строки, где нажади кнопку. Повторное нажатие на кнопку скроет контейнер.

Решите задачу при помощи фреймворков, а мы потом ее разберем по полочкам.

Link to comment
Share on other sites

Пф.. сейчас я попробую обрисовать предыдущий разговор на отстранённом примере.

Автор: нужно ли пользоваться гаечными ключами?

Юзер: ДА

Автор: нафига? ведь проще руками!

Юзер: не согласен! это гемор!

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

Резюме: на решение вашей задачи самым простым методом нужна одна минута. Естесственно, "ковыряться в носу гаечным ключом" не стоит там, где это Глупо. Давайте поставим задачу сравнимую с "откручиванием болта".

Мой пример задачи: реализовать псевдо-фреймовую структуру на ЖС. Ну то есть экран разделён на блоки (словно фреймами). Разделители блоков можно двигать, можно складывать одним нажатием и т.п. Ну представьте рабочее поле Дримвивера, Флеша или любого другого редаткора. Вот что-то в этом роде.

Link to comment
Share on other sites

Пф.. сейчас я попробую обрисовать предыдущий разговор на отстранённом примере.

Неверное толкование.

Разговор сводится к другому.

Представьте, что вы строите суперкар. Вам дали некого робота сборщика. Его задача - облегчить ваш труд по сборке. Робот умеет скручивать детали, приваривать их одну к другой, может красить детали, может разбирать детали автоматически. Вы решаете, что робот вам серьезно облечит задачу, и начинаете пробовать им пользоваться. Вы собираете какую-то часть, на первом этапе вам кажется, что вы закончите работу очень быстро, все продвигается хорошо, готовы базовые куски. Но через время вы начинаете мыслить категориями функциональности робота. Вместо простого решения вы начинаете создавать сложные команды, потому что вам все еще кажется, что робот ускоряет вам работу. Так как костылей в работе становится больше, суперкар теряет легкость и красоту, потому что робот не смог что-то реализовать.

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

Link to comment
Share on other sites

  • 4 weeks later...
Представьте, что вы строите суперкар. Вам дали некого робота сборщика. Его задача - облегчить ваш труд по сборке. Робот умеет скручивать детали, приваривать их одну к другой, может красить детали, может разбирать детали автоматически. Вы решаете, что робот вам серьезно облечит задачу, и начинаете пробовать им пользоваться. Вы собираете какую-то часть, на первом этапе вам кажется, что вы закончите работу очень быстро, все продвигается хорошо, готовы базовые куски. Но через время вы начинаете мыслить категориями функциональности робота. Вместо простого решения вы начинаете создавать сложные команды, потому что вам все еще кажется, что робот ускоряет вам работу. Так как костылей в работе становится больше, суперкар теряет легкость и красоту, потому что робот не смог что-то реализовать.

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

Умные люди так и делают ^_^ Робот (например, jQuery) делает сложные, муторные, рутинные работы, вроде кросс-браузерного поиска элементов по ЦСС-селекторам :P, а уже обработку найденного осуществляет простой код скрипта. 54КБ скриптов -- это, бесспорно, не так мало, но это не страшная жертва по сравнению с писаниной руками всех этих действий. Например, в каждом браузере нужно по-разному добавлять обработчики событий, вычислять высоту окна браузера, работать с аяксом и т.п. Фреймворк избавляет нас от этой му..ты. Это плохо? :P

Link to comment
Share on other sites

Умные люди так и делают :) Робот (например, jQuery) делает сложные, муторные, рутинные работы, вроде кросс-браузерного поиска элементов по ЦСС-селекторам :(,

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

Покажите мне фреймворк, который умеет находить парента с нужным именем ноды. А с нужным классом? А с наличием нужного свойства или атрибута?

Уверен, что такие есть, но кроме того стоит и посмотреть на код, который это делает.

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

Одна функция.

вычислять высоту окна браузера

Одна функция.

, работать с аяксом и т.п.

У меня 6 кил несжатого текста, но очень специфический код.

Фреймворк избавляет нас от этой му..ты. Это плохо? :)

Плохо наступает тогда, когда вместо одной функции используется 30 килобайт ненужного барахла.

Link to comment
Share on other sites

Это вредит обучению и пониманию этих мелких нюансов. :) И если задача маленькая, и средства не оправданы, то библиотеки в данном случае - это плохо.

Мне представляется всё немного сложнее: одно дело -- вникнуть в нюансы JS такого, как он описан у w3c, и совсем другое -- посмотреть как это всё реализованно, например, у ЧУДЕСНОЙ фирмы майкрософт. Второе -- труд неблагодарный, и не влечет глубокого понимания чего-либо, кроме идиотизма некоторых производителей ПО. Что касается размера задачи, то в живых проектах задачи имеют обыкновение расти вширь и вбок, и тут как раз-таки будет очень дальновидным сразу использовать нормальную библиотеку.

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

По-моему, совсем наоборот - не зацикливаешься на деталях, а делаешь то, что нужно именно тебе.

Покажите мне фреймворк, который умеет находить парента с нужным именем ноды. А с нужным классом? А с наличием нужного свойства или атрибута?

Уверен, что такие есть, но кроме того стоит и посмотреть на код, который это делает.

Честно говоря, я не очень понимаю Ваш жаргон (парента с нужным именем ноды), но если Вы выразитесь точнее, думаю, большинство JS-фреймворков это осилят. Что касается кода, то сдется мне его совсем не дураки пишут, и вряд ли он сильно плох :(

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

Одна функция.

вычислять высоту окна браузера

Одна функция.

Именно так. Одна функция. НО вот только ЗАЧЕМ кажому программисту реализовывать эти функции самостоятельно?! О_о

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

, работать с аяксом и т.п.

У меня 6 кил несжатого текста, но очень специфический код.

Фреймворк избавляет нас от этой му..ты. Это плохо? :)

Плохо наступает тогда, когда вместо одной функции используется 30 килобайт ненужного барахла.

Если учесть, что нормальный браузер после первого обращения их закэширует (а основная масса сайтов ориентирована на постоянных юзеров), то 30-150КБ -- это совсем ерунда. К тому же, потом обязательно понадобятся ещё функции...

То же самое касается CSS-фреймворков.

А многие PHP-фреймворки вообще подталкивают к написанию приложений с четкой структурой и работой. Уменьшается риск XSS, SQL-инъекций. Без фреймворка (особенно на весьма "дырявом" языке PHP) все эти угрозы весьма опасны, их трудно заблокировать, особенно если не шарить в этом. А многие в этом шарят?!

Link to comment
Share on other sites

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

Написанную своими руками. Это да. Чужую - нет. Потому что времени на разбор чужого кода, в случае ошибки в коде фреймворка, можно потратить в разы больше, чем написать свою функцию заново.

По-моему, совсем наоборот - не зацикливаешься на деталях, а делаешь то, что нужно именно тебе.

И сколько действительно сложных и удобных скриптов ты написал?

Честно говоря, я не очень понимаю Ваш жаргон (парента с нужным именем ноды), но если Вы выразитесь точнее, думаю, большинство JS-фреймворков это осилят. Что касается кода, то сдется мне его совсем не дураки пишут, и вряд ли он сильно плох :)

Какой такой жаргон?

<div class="super">
<span>
<b>
<a href="#">link</a>
</b>
</span>
</div>

Мне нужно при нажатии на ссылку найти parentNode у которого nodeName=="SPAN", или parentNode у которого className содержит имя класса "super". Или parentNode, у которого существует некое свойство или атрибут "tst" например.

Именно так. Одна функция. НО вот только ЗАЧЕМ кажому программисту реализовывать эти функции самостоятельно?! О_о

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

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

Link to comment
Share on other sites

В ближайшем будущем единого стандарта JavaScript для браузеров не предвидится. То что если ты знаешь все нюансы JS в разных браузерах выводит тебя на более высокий уровень. Ты становишься гибким программистом.

Edited by Ялекс
Link to comment
Share on other sites

  • 2 weeks later...
Написанную своими руками. Это да. Чужую - нет. Потому что времени на разбор чужого кода, в случае ошибки в коде фреймворка, можно потратить в разы больше, чем написать свою функцию заново.

1. Это зависит от размера проекта и требований к нему. Если вы пишете веб-интерфейс к программе управления ядерным оружием (что само по себе забавно), то стоит подумать, можно ли доврять фреймворку. Если же проект небольшой, то пару таких общих функций можно и самому набросать, хотя смысла в этом я не вижу, если проект побольше, то лучше взять фреймворк. Может только для огромного проекта (когда у вас пара сотен программистов не занятых) имеет смысл писать свой фреймворк. Дело в том, что прогресс не дремлет и на поддержку развития своего фреймворка приходится тратить СВОЕ время, а чужой развивается сам. Конечно, если не выбрать сразу плохой фреймворк. Я очень высоко ценю своё время и не хочу "буксовать" на развитии самописных библиотек. Разьве только в целях развития, но это другая тема.

2. Разбирать чужой код -- глупость. Надо читать доки ("они рулез" (С)) и потратить в разы меньше времени.

И сколько действительно сложных и удобных скриптов ты написал?

С каждым месяцем -- всё больше :rolleyes: Я развиваюсь, не стою на месте упершись лбом в стену :unsure: .

Какой такой жаргон?

<div class="super">
<span>
<b>
<a href="#">link</a>
</b>
</span>
</div>

Мне нужно при нажатии на ссылку найти parentNode у которого nodeName=="SPAN", или parentNode у которого className содержит имя класса "super". Или parentNode, у которого существует некое свойство или атрибут "tst" например.

Не занимался этим, но думаю это достаточно элементарно.

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

Понимать суть -- да, понимать особенности браузеров -- бред.

В ближайшем будущем единого стандарта JavaScript для браузеров не предвидится. То что если ты знаешь все нюансы JS в разных браузерах выводит тебя на более высокий уровень. Ты становишься гибким программистом.

Я предпочитаю так: "Я знаю библиотеку которая скрывает от меня кроссбраузерные особенности (это называется "инкапсуляцией") и вместо кода для каждого браузера пишу всё единообразно => я гибкий программист".

Это лучше (помимо удобства, логичности и простоты) ещё и тем, что при появлении нового браузера, новых диалектов JS, я беру новую версию фреймворка, а не перелопачиваю весь свой код. Можете не соглашаться, но именно это и есть другой уровень имхо.

Хотя в Ваших словах есть смысл -- для разработчика фреймворка. Эти люди вникают в суть диалектов и тем самым избавляют остальных людей от этой неблагодарной работы (за что им почет и хвала, и , кажется, солидная денежная компенсация).

Зачем всем бороться с одной и той же проблемой? Зачем нам каждому свой фреймворк? Разумно и правильно тут объединить усилия и сделать несколько общих. Выбирай какой хочешь. А если что не нравится -- переделывай как угодно, код-то открытый (кроме такой лажи как MS MFC и т.п.) -- это для товарища s0rr0w.

Edited by Sochog
Link to comment
Share on other sites

Разбирать чужой код — глупость. Надо читать доки («они рулез» ©)

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

Link to comment
Share on other sites

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

А я написал свою надстройку (фреймворком это назвать язык не поворачивается), и выиграл для всего развития проекта. Взял бы чужое - сидел бы бесконечно писал код.

> 2. Разбирать чужой код -- глупость. Надо читать доки ("они рулез" (С)) и потратить в разы меньше времени.

В доках, конечно же, описано, как исправлять баги во фреймворке...

> С каждым месяцем -- всё больше :rolleyes: Я развиваюсь, не стою на месте упершись лбом в стену ;) .

А я с каждым месяцом все меньше. Потому что концепция другая. Зачем писать больше, если можно повторно использовать код?

> Не занимался этим, но думаю это достаточно элементарно.

Это действительно элементарно. Но покажите мне фреймворк, в котором написано это элементарное. Никто мне до сих пор этого не показал. А потому что все думают шаблонно. Нужен доступ к элементу? А вот тебе класс или имя ноды, или ID. Но никто не думает, что можно просто подняться на уровень выше и получить нужный элемент без дополнительных идентификаторов.

> Понимать суть -- да, понимать особенности браузеров -- бред.

Скажите, чем отличается реализация стека event-listener'ов IE и FF?

> Зачем всем бороться с одной и той же проблемой? Зачем нам каждому свой фреймворк? Разумно и правильно тут объединить усилия и сделать несколько общих. Выбирай какой хочешь. А если что не нравится -- переделывай как угодно, код-то открытый (кроме такой лажи как MS MFC и т.п.) -- это для товарища s0rr0w.

А какой фреймворк лучше всего подходит для разработки интерфейсных решений? :unsure:

Link to comment
Share on other sites

Гибкий программист и гибкий код это не одно и то же...

Согласен с Вами. Конечно, человек знающий все тонкости сможет больше, нежели человек знающий только фреймворк. Это разные уровни.

Вот только трудозатраты на изучение одного и другого совсем разные. И фреймворкер легче изучит тонкости, чем совсем новичек -- хотя бы по тому же коду фреймворка... В общем, это, имхо, разумный промежуточный этап, дальше которого я пока не планирую двигаться... :( Но не окончательный, сама собой, не верх мастерства.

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

Разумеется фреймворк может не все. Человек использующий фреймворк рано или поздно столкнется с этим и придется мутить самому Се ля ви:(

Но ведь я и не говорю, что фреймворк -- это панацея, которая всё сделает за нас. Он существенно облегчит жизнь и ускорит разработку -- это тоже немало.

А я написал свою надстройку (фреймворком это назвать язык не поворачивается), и выиграл для всего развития проекта. Взял бы чужое - сидел бы бесконечно писал код.

> 2. Разбирать чужой код -- глупость. Надо читать доки ("они рулез" (С)) и потратить в разы меньше времени.

В доках, конечно же, описано, как исправлять баги во фреймворке...

> С каждым месяцем -- всё больше Я развиваюсь, не стою на месте упершись лбом в стену .

А я с каждым месяцом все меньше. Потому что концепция другая. Зачем писать больше, если можно повторно использовать код?

> Не занимался этим, но думаю это достаточно элементарно.

Это действительно элементарно. Но покажите мне фреймворк, в котором написано это элементарное. Никто мне до сих пор этого не показал. А потому что все думают шаблонно. Нужен доступ к элементу? А вот тебе класс или имя ноды, или ID. Но никто не думает, что можно просто подняться на уровень выше и получить нужный элемент без дополнительных идентификаторов.

> Понимать суть -- да, понимать особенности браузеров -- бред.

Скажите, чем отличается реализация стека event-listener'ов IE и FF?

> Зачем всем бороться с одной и той же проблемой? Зачем нам каждому свой фреймворк? Разумно и правильно тут объединить усилия и сделать несколько общих. Выбирай какой хочешь. А если что не нравится -- переделывай как угодно, код-то открытый (кроме такой лажи как MS MFC и т.п.) -- это для товарища s0rr0w.

А какой фреймворк лучше всего подходит для разработки интерфейсных решений? :(

Сдается мне, у Вас какое-то "странное" мнение относительно того, как люди используют фреймворк.

Мои тезисы:

1. фреймворки упрощают жизнь и ускоряют разработку.

2. фреумворки в пределах своих ограничений помогают забыть о кроссбраузерности

3. фреймворки не надо поддерживать -- этим занимаются другие, весьма неглупые люди, а мы пользуемся (совершенно бесплатно)

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

Если Вы считаете, что "Умные люди" (мыслящие не шаблонно :P))) не используют фреймворки -- то Вы считаете глупыми такие фирмы, как Google, w3c, DELL, Intel.

Но вместе с тем, я не утверждаю, что фреймворки могут всё (найдете в моих высказываниях -- цитируйте) и избавят нас от всех проблем.

Если вы не согласны с моими тезисами - пишите предметно, не собирайте бред. Ясен перец, что есть то, чего фреймворк не может, но это не значит, что нужно от него отказаться совсем и не использовать даже то, что он может :( (имхо).

Link to comment
Share on other sites

Сдается мне, у Вас какое-то "странное" мнение относительно того, как люди используют фреймворк.

Почему странное? Очень даже не странное.

> 1. фреймворки упрощают жизнь и ускоряют разработку.

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

> 2. фреумворки в пределах своих ограничений помогают забыть о кроссбраузерности

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

> 3. фреймворки не надо поддерживать -- этим занимаются другие, весьма неглупые люди, а мы пользуемся (совершенно бесплатно)

Не забывайте про временной лаг. Иногда от возникновения ошибки до ее исправления может пройти пол года. Потому что этим занимаются другие люди. Хоть и весьма неглупые.

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

А зачем? Смысл в наращивани в фреймворке фич, которые будут востребованы один раз из тысячи?

Если Вы считаете, что "Умные люди" (мыслящие не шаблонно :())) не используют фреймворки -- то Вы считаете глупыми такие фирмы, как Google, w3c, DELL, Intel.

Подробнее с этого места... (запасся попкорном)

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

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

Link to comment
Share on other sites

строчка из исходного кода страницы http://validator.w3.org/:

	<script type="text/javascript" src="scripts/mootools.js"></script>

Точно такая же есть на странице http://jigsaw.w3.org/css-validator/

А вот строчка с сайта http://www.dell.ru/

<script language="javascript" src="http://i.dell.com/images/global/js/lib/jquery-1.2.2a.js"></script>

Я надеюсь вы смысл этих строчек понимаете?

не могу подтвердить исходным кодом (он какой-то зашифрованно-запакованный хитро-й), но весь сервис gmail.com построен на jQuery. Вы пользовались gmail? сделайте проект такого же масштаба без фреймворка -- продолжим беседу.

Ещё что? ( я проигнорировал те фразы, в которых не нашел смысла)

Link to comment
Share on other sites

Я надеюсь вы смысл этих строчек понимаете?

Аааааа... Вот вы про что. Кто делал сайты для всех этих компаний? Это к тому, что сама компания не использует фреймворки, это кто-то разработал продукт с использованием фреймворков. И врядли DELL настаивал на том, что нужно обязательно их использовать.

Вы пользовались gmail? сделайте проект такого же масштаба без фреймворка -- продолжим беседу.

Легко! В Гмейл нет ничего сложного.

Ещё что? ( я проигнорировал те фразы, в которых не нашел смысла)

Конечно, особенно меня порадовал пропуск вопроса про то, каким местом фреймворки ускоряют разработку. Нет смысла в данном вопросе, ага... Верю, ибо нелепо!

:(

Link to comment
Share on other sites

Ага, считаем. В js-программировании. :(

Google - вряд-ли.

Просто они понимают, что надо делать не круче («мы такие умные — изобретаем свой велосипед») а эффективнее. Причем не в плане производительности кода, а в плане скорости разработки.

В частности если в гугле работают такие глупые программисты, а вы такие умные, почему вы еще не там? Вы могли бы легко доказать свое превосходство ;-) (Вопрос саркастический, ответа не требует).

Что касается фирм, не занимающихся непосредственно веб-технологиями, то, возможно, вы в чем-то правы.

Link to comment
Share on other sites

Просто они понимают, что надо делать не круче («мы такие умные — изобретаем свой велосипед») а эффективнее.

А эффективнее, это как? Кто мерял эту самую эффективность?

> Причем не в плане производительности кода, а в плане скорости разработки.

Везде присутствует мифическая скорость разработки... Но покажите мне хоть один отчет компании, которая бы показала эффективность данного подхода.

В частности если в гугле работают такие глупые программисты, а вы такие умные, почему вы еще не там? Вы могли бы легко доказать свое превосходство ;-) (Вопрос саркастический, ответа не требует).

Я не говорил что в гугле работают глупые программисты. Но их творения не представляют для меня никакой сложности. И не несут ничего интересного. И я не собираюсь доказывать кому-то свое превосходство, глупо это. Вот, например, zeroglif, он собаку съел на JS. Мне далеко до него, но я туда и не стремлюсь, это не мой путь.

Что касается фирм, не занимающихся непосредственно веб-технологиями, то, возможно, вы в чем-то правы.

Я не видел опровержения своих слов, и я бы сменил све мнение на противоположное, если бы имел успешную историю применения фреймворков для создания веб-приложений.

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

Кстати, zeroglif, есть тема для обсуждения.

http://forum.htmlbook.ru/index.php?showtopic=12183

Link to comment
Share on other sites

Ну что касается скорости разработки, то для меня, как для не знающего JS, вполне ощутима разница между реализацией задачи с использованием фреймворка, или долгим и нудным разбором отличий браузеров и поиском ошибок. :-)

Link to comment
Share on other sites

Смотрел реализацию Gmail. Там разве есть фреймверки?

Обычно вещи которые реализуются фреймверком, можно реализовать 20 строками CSS+JS. Просто нужна смекалка.

А если смекалки нет, то берите фреймверк и, как говориться, ваяйте... Но не факт, что конечный продукт будет быстрым и легким.

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

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy