XMacro

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

Под MS Windows для этих целей существует AutoHotkey, распространяемая под GPL лицензией,

В GNU/Linux на помощь приходит xmacro. Это небольшая программа позволяющая записывать и воспроизводить нажатие клавиш, движения и нажатия кнопок мыши. Работает из консоли.

Установка

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

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

sudo apt-get install xmacro

Процесс

Кратко о том, что мы будем делать:

  1. Планирование - поставить задачу и спланировать как это будет выглядеть в виде последовательной схемы действий.
  2. Записать с помощью xmacro
  3. Редактирование/отладка полученной записи:
  • очистить лишние манипуляции, если таковые имеются
  • определить места, где необходимы задержки
  • опытным путем сократить задержки до минимума

Комбинирование

Xmacro можно сочетать с любыми другими программами для достижения простоты использования или сложных задач. Вчасности можно использовать:

Планировщик: для запуска в определенное время, по расписанию.

Жесты мышью: для упрощения запуска без использования клавиатуры.

Пример №1

Планирование

Задача: запустить DeaDBeeF на другом рабочем столе, подцепить конкретный плейлист, запустить воспроизведение, свернуть в трей.

Итак, я определил последовательность действий как следующую:

  1. Ctrl+Alt+Right — переключиться на другой рабочий стол
  2. Alt+F2 — открыть окно запуска
  3. «deadbeef» — ввести название программы
  4. Enter — нажать ввод
  5. Alt+F — открыть раздел «Файл» панели инструментов
  6. +++++ — спуститься до «Загрузить плейлист»
  7. Enter — нажать ввод
  8. Alt+Home — открыть домашнюю папку
  9. playlist.dbpl — ввести название плейлиста
  10. Enter — нажать ввод
  11.  — перейти на первый трек открытого плейлиста
  12. Enter — нажать ввод, запустив воспроизведение
  13. Alt+F9 — свернуть окно плеера
  14. Ctrl+Alt+Left - переключиться на предыдущий рабочий стол

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

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

Запись

Пришло время записать последовательность необходимых нам действий. Для этого запускаем xmacro в режиме записи из консоли:

~$ xmacrorec2 > testing.macro
Server VendorRelease: 10900000
XRecord for server ":0.0" is version 1.13.

Press the key you want to use to end the application. This key can be any key,
as long as you don't need it while working with the remote display.
A good choice is Escape.

На данном этапе нам предлагают нажать клавишу, после которой начнется запись и которой она будет завершена. Программа рекомендует нажать «Escape». Ну что же не будем нарушать традицию. Следует запоминать нажатую клавишу, иначе вы не сможете завершить запись.

The chosen quit-key has the keycode: 9
XQueryPointer returned: 1
Got Start Of Data
Skipping...
- Skipping stale KeyRelease event. 1

Запись началась. Я выполнил ранее запланированные манипуляции. И завершил запись нажатием «Escape».

Got QuitKey, so exiting...
xmacrorec2: Exiting.

Посмотрим что получилось:

MotionNotify 781 638
KeyStrPress Control_L
KeyStrPress Alt_L
KeyStrPress Right
KeyStrRelease Right
KeyStrRelease Alt_L
KeyStrRelease Control_L
KeyStrPress Alt_L
KeyStrPress F2
KeyStrRelease Alt_L
KeyStrRelease F2
KeyStrPress d
KeyStrRelease d
KeyStrPress e
KeyStrRelease e
KeyStrPress a
KeyStrRelease a
KeyStrPress d
KeyStrRelease d
KeyStrPress b
KeyStrRelease b
KeyStrPress e
KeyStrRelease e
KeyStrPress e
KeyStrRelease e
KeyStrPress f
KeyStrRelease f
KeyStrPress Return
KeyStrRelease Return
KeyStrPress Alt_R
KeyStrPress a
KeyStrRelease a
KeyStrRelease Alt_R
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Return
KeyStrRelease Return
KeyStrPress p
KeyStrRelease p
KeyStrPress l
KeyStrRelease l
KeyStrPress a
KeyStrRelease a
KeyStrPress y
KeyStrRelease y
KeyStrPress l
KeyStrRelease l
KeyStrPress i
KeyStrRelease i
KeyStrPress s
KeyStrRelease s
KeyStrPress t
KeyStrRelease t
KeyStrPress period
KeyStrRelease period
KeyStrPress d
KeyStrRelease d
KeyStrPress b
KeyStrRelease b
KeyStrPress p
KeyStrRelease p
KeyStrPress l
KeyStrRelease l
KeyStrPress Return
KeyStrRelease Return
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Return
KeyStrRelease Return
KeyStrPress Alt_L
KeyStrPress F9
KeyStrRelease F9
KeyStrRelease Alt_L
KeyStrPress Control_L
KeyStrPress Alt_L
KeyStrPress Left
KeyStrRelease Left
KeyStrRelease Alt_L
KeyStrRelease Control_L

Редактирование и отладка

Как видно на выходе мы получили список команд для xmacro повторяющих наши действия. Часть ненужных команд, если вы выполнили лишние манипуляции, нужно подчистить. В частности первую строчку, фиксирующую движение мыши.

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

Для первого тестового запуска можно использовать задержку после каждого действия, указываемая с помощью ключа -d (по умолчанию задержка 10 миллисекунд). Например:

cat testing.macro | xmacroplay -d 100 :0.0

В целом все нормально. Однако не всем нажатиям необходима столь большая задержка, поэтому для качественного быстрого запуска нужно выставить задержки вручную командой «Delay n» где это необходимо.

Опытным путем, определив нужное значение, я установил всего три задержки по секунде. Получилось:

KeyStrPress Control_L
KeyStrPress Alt_L
KeyStrPress Right
KeyStrRelease Right
KeyStrRelease Alt_L
KeyStrRelease Control_L
KeyStrPress Alt_L
KeyStrPress F2
KeyStrRelease Alt_L
KeyStrRelease F2
Delay 1
KeyStrPress d
KeyStrRelease d
KeyStrPress e
KeyStrRelease e
KeyStrPress a
KeyStrRelease a
KeyStrPress d
KeyStrRelease d
KeyStrPress b
KeyStrRelease b
KeyStrPress e
KeyStrRelease e
KeyStrPress e
KeyStrRelease e
KeyStrPress f
KeyStrRelease f
KeyStrPress Return
KeyStrRelease Return
Delay 1
KeyStrPress Alt_R
KeyStrPress a
KeyStrRelease a
KeyStrRelease Alt_R
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Down
KeyStrRelease Down
KeyStrPress Return
KeyStrRelease Return
Delay 1
KeyStrPress p
KeyStrRelease p
KeyStrPress l
KeyStrRelease l
KeyStrPress a
KeyStrRelease a
KeyStrPress y
KeyStrRelease y
KeyStrPress l
KeyStrRelease l
KeyStrPress i
KeyStrRelease i
KeyStrPress s
KeyStrRelease s
KeyStrPress t
KeyStrRelease t
KeyStrPress period
KeyStrRelease period
KeyStrPress d
KeyStrRelease d
KeyStrPress b
KeyStrRelease b
KeyStrPress p
KeyStrRelease p
KeyStrPress l
KeyStrRelease l
KeyStrPress Return
KeyStrRelease Return
KeyStrPress Down
KeyStrRelease Down
Delay 1
KeyStrPress Return
KeyStrRelease Return
KeyStrPress Alt_L
KeyStrPress F9
KeyStrRelease F9
KeyStrRelease Alt_L
KeyStrPress Control_L
KeyStrPress Alt_L
KeyStrPress Left
KeyStrRelease Left
KeyStrRelease Alt_L
KeyStrRelease Control_L

Проверяем, запустив без задержки.

cat testing.macro | xmacroplay :0.0

Проблемы воспроизведения

Для тех, у кого появится следующая ошибка:

~$ xmacrorec2 > testing.macro
Server VendorRelease: 70101000
Xlib: extension "RECORD" missing on display ":0.0".
xmacrorec2: XRecord extension not supported on server ":0.0"

Это связано с отсутствием нужной строчки в xorg.conf

sudo gedit /etc/X11/xorg.conf

Ищем раздел "Module" и добавляем туда следующую строчку:

Load "record"

Сохраняем и закрываем текстовый редактор.

Автозапуск

Теперь добавим полученную нами запись в автозапуск. Для этого нам нужно выставить в начале записи задержку, учитывающую время необходимое на загрузку графического окружения. У меня это 6 сек. Затем создадим элементарный bash скрипт, воспроизводящий запись и добавим его в автозапуск:

#!/bin/sh
cat ~/testing.macro | xmacroplay  ":0.0"

Можно использовать планировщик для запуска по определенному расписанию. Например, установим Alarm Clock (Будильник):

sudo apt-get intsall alarm-clock

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

Пример №2

Итак, задача: упростить копирование выделенного текста с открытой страницы в текстовый редактор.

Реализация: Здесь я решил создать два скрипта. Первый для первого запуска — копирует текст, запускает OpenOffice, затем вставляет текст в него. Второй для повторных запусков просто вставляет текст в конец документа.

Первый:

  1. Ctrl+С — скопировать буфер обмена выделенный текст
  2. Ctrl+Alt+Left — переключится на другой рабочий стол
  3. Alt+F2 — открыть окно запуска
  4. oowriter — ввести для запуска OpenOffice
  5. Enter - нажать ввод
  6. Ctrl+V — вставить из буфера обмена скопированный текст
  7. Ctrl+Alt+Right — переключится на предыдущий рабочий стол

Второй:

  1. Ctrl+С — скопировать буфер обмена выделенный текст
  2. Ctrl+Alt+Left — переключится на другой рабочий стол
  3. Ctrl+End — перейти в конец документа
  4. Ввод — сделать отступ
  5. Ввод — сделать отступ
  6. Ctrl+V — вставить из буфера обмена скопированный текст
  7. Переключится на предыдущий рабочий стол

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

Первый

KeyStrPress Control_L
KeyStrPress c
KeyStrRelease Control_L
KeyStrRelease c
KeyStrPress Control_L
KeyStrPress Alt_L
KeyStrPress Right
KeyStrRelease Right
KeyStrRelease Alt_L
KeyStrRelease Control_L
KeyStrPress Alt_L
KeyStrPress F2
KeyStrRelease Alt_L
KeyStrRelease F2
Delay 1
KeyStrPress o
KeyStrRelease o
KeyStrPress o
KeyStrRelease o
KeyStrPress w
KeyStrRelease w
KeyStrPress r
KeyStrRelease r
KeyStrPress i
KeyStrRelease i
KeyStrPress t
KeyStrRelease t
KeyStrPress e
KeyStrRelease e
KeyStrPress r
KeyStrRelease r
KeyStrPress Return
KeyStrRelease Return
Delay 1
KeyStrPress Control_L
KeyStrPress End
KeyStrRelease End
KeyStrRelease Control_L
KeyStrPress Return
KeyStrRelease Return
KeyStrPress Return
KeyStrRelease Return
KeyStrPress Control_L
KeyStrPress v
KeyStrRelease Control_L
KeyStrRelease v
KeyStrPress Control_L
KeyStrPress Alt_L
KeyStrPress Left
KeyStrRelease Left
KeyStrRelease Alt_L
KeyStrRelease Control_L

Второй

KeyStrPress Control_L
KeyStrPress c
KeyStrRelease Control_L
KeyStrRelease c
KeyStrPress Control_L
KeyStrPress Alt_L
KeyStrPress Right
KeyStrRelease Right
KeyStrRelease Alt_L
KeyStrRelease Control_L
KeyStrPress Control_L
KeyStrPress End
KeyStrRelease End
KeyStrRelease Control_L
KeyStrPress Return
KeyStrRelease Return
KeyStrPress Control_L
KeyStrPress v
KeyStrRelease Control_L
KeyStrRelease v
KeyStrPress Control_L
KeyStrPress Alt_L
KeyStrPress Left
KeyStrRelease Left
KeyStrRelease Alt_L
KeyStrRelease Control_L

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

sudo apt-get install easystroke

Первой записи присваиваю жест в виде буквы «С» с закорючкой, для второго просто «С». В «Тип» выбираю «Команда», прописав в поле

cat ~/copy_paste-1.macro | xmacroplay ":0.0"

для первой

cat ~/copy_paste-2.macro | xmacroplay ":0.0"

и для второй.

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

Создание bash скрипта

Можно запихнуть запись в bash скрипт. Втарая запись выглядеть следующим образом:

#!/bin/sh
echo "KeyStrPress Control_L\nKeyStrPress c\nKeyStrRelease Control_L\nKeyStrRelease c\nKeyStrPress Control_L\nKeyStrPress Alt_L\nKeyStrPress Right\nKeyStrRelease Right\nKeyStrRelease Alt_L\nKeyStrRelease Control_L\nKeyStrPress Control_L\nKeyStrPress End\nKeyStrRelease End\nKeyStrRelease Control_L\nKeyStrPress Return\nKeyStrRelease Return\nKeyStrPress Control_L\nKeyStrPress v\nKeyStrRelease Control_L\nKeyStrRelease v\nKeyStrPress Control_L\nKeyStrPress Alt_L\nKeyStrPress Left\nKeyStrRelease Left\nKeyStrRelease Alt_L\nKeyStrRelease Control_L" |xmacroplay ":0.0"

Где «\n» перевод строки, добавляемый в конце каждой команды, в результате запись должна быть идти одной строкой.

На последок полезные bash скрипты записей:

Запуск Nautilus в двухпанельном режиме:

#!/bin/sh
nautilus
echo "Delay 1\nKeyStrPress F3\nKeyStrRelease F3\n"|xmacroplay ":0.0"

P.S. В Ubuntu man XMacro лежит /usr/share/doc/xmacro/README

0
Ваша оценка: Нет

Комментарии

20171118caihuali

true religion jeans

reebok trainers

michael kors handbags

pandora charms sale clearance

michael kors factory outlet

ugg boots

oakley sunglasses

oakley sunglasses

ray ban sunglasses

ugg boots clearance

mac cosmetics

pandora jewelry

ugg outlets

nike store uk

ferragamo outlet

ralph lauren polo shirts

michael kors handbags

pandora charms

coach outlet

coach outlet

kobe bryant shoes

cheap snapbacks

nike foamposite

cheap jordans

adidas nmd

oakley sunglasses

ray ban sunglasses

ray ban sunglasses

nike roshe one

canada goose outlet

ugg outlet

ferragamo outlet

coach outlet

ugg outlet

ugg boots

ralph lauren outlet

canada goose outlet

canada goose outlet

canada goose outlet

michael kors outlet

fitflops shoes

ugg boots clearance

polo outlet

mulberry bags

ugg boots

adidas outlet store

uggs outlet

ugg outlet

moncler jackets

cheap jordans

fitflops sale clearance

ugg outlet

christian louboutin uk

soccer shoes

michael kors outlet

cheap nfl jerseys

cheap snapbacks

louboutin shoes

chrome hearts

canada goose outlet

air huarache

uggs outlet

michael kors

nba jerseys

michael kors wallets

polo ralph lauren

nike shoes

fitflops sale clearance

christian louboutin shoes

cheap mlb jerseys

mont blanc pens

air max trainers

polo ralph lauren

ed hardy clothing

ugg outlet

mcm outlet

michael kors outlet

michael kors outlet online

nfl jersey wholesale

ysl outlet

tory burch outlet

michael kors outlet online

jordan shoes

michael kors outlet

canada goose outlet

canada goose jackets

michael kors outlet

nike air force 1

michael kors outlet

ugg outlet

canada goose cyber monday

cartier outlet

michael kors outlet online

coach outlet online

canada goose jackets

uggs outlet

coach factory outlet

ferragamo shoes

ray ban sunglasses

polo ralph lauren

oakley sunglasses

michael kors outlet

michael kors outlet

adidas uk

polo ralph lauren

fitflops

cheap jordans

burberry outlet

vans shoes

michael kors outlet

nfl jerseys wholesale

nike trainers

uggs outlet

ugg boots

coach outlet

michael kors

christian louboutin shoes

nike trainers

oakley sunglasses

ray ban sunglasses

christian louboutin outlet

oakley sunglasses

ray ban sunglasses

oakley sunglasses

mulberry bags

ugg boots clearance

fitflops outlet

cazal sunglasses

coach outlet

polo outlet

ralph lauren polo

michael kors outlet

pandora jewelry

ugg outlet

uggs outlet

coach outlet

uggs outlet

ugg boots clearance

michael kors outlet

coach outlet

michael kors handbags

ferragamo outlet

mulberry outlet

ralph lauren uk

swarovski crystal

nike outlet

reebok outlet store

coach outlet online

coach outlet

vans outlet

nike shoes

oakley sunglasses

oakley sunglasses

true religion jeans

cheap jerseys

oakley sunglasses

coach handbags

true religion jeans

mont blanc pens

kate spade outlet

canada goose outlet

polo ralph lauren

swarovski outlet

canada goose outlet

coach outlet

moncler outlet

coach outlet

marc jacobs outlet

coach outlet online

longchamp handbags

polo ralph lauren

fitflops sale

lacoste soldes

fitflops shoes

ralph lauren pas cher

birkenstock outlet

longchamp pas cher

polo ralph lauren

lacoste polo shirts

coach outlet

coach outlet online

nike air max 90

nike roshe

adidas trainers

nike store

mulberry handbags

ray bans

pandora charms sale clearance

michael kors bags

chrome hearts outlet

adidas wings

new balance shoes

oakley sunglasses

ray ban sunglasses

ugg outlet

true religion jeans

ugg outlet

lebron james shoes

coach outlet online

canada goose outlet

coach outlet

coach outlet online

longchamp pliage

polo ralph lauren

coach factory outlet

kobe 9

longchamp outlet

mulberry sale

ugg outlet

kate spade outlet

ralph lauren polo shirts

swarovski outlet

ugg outlet

christian louboutin outlet

christian louboutin online

puma outlet

tory burch shoes

canada goose jackets

ralph lauren outlet

true religion outlet

montblanc pens

canada goose jackets

tory burch outlet

oakley sunglasses

tory burch outlet

ugg black friday

soccer jerseys

hermes belt

coach factory outlet

air max 90

michael kors black friday

canada goose outlet

nike outlet

kate spade outlet

burberry outlet

michael kors outlet

kevin durant shoes

tory burch outlet

ugg boots

ugg outlet

salomon shoes

coach outlet

tory burch outlet

prada handbags

ugg outlet

christian louboutin shoes

polo ralph lauren

jordan shoes

canada goose outlet

oakley sunglasses

hermes birkin

oakley sunglasses

thomas sabo

mulberry handbags

coach outlet

michael kors outlet

ugg boots clearance

prada outlet

coach outlet

ugg outlet

basketball shoes

jordan shoes

ugg outlet

nike free 5

canada goose outlet

canada goose outlet

ray ban sunglasses

ray ban sunglasses

kate spade outlet

canada goose outlet

michael kors outlet

ugg boots

football shirts

canada goose outlet

tory burch outlet

michael kors outlet

canada goose outlet

oakley sunglasses

nike air max 2015

ray ban sunglasses

ferragamo outlet

uggs outlet

oakley sunglasses

swarovski crystal

coach outlet canada

ray bans

polo ralph lauren

canada goose outlet

michael kors outlet

adidas nmd

polo ralph lauren

oakley sunglasses wholesale

michael kors

ugg outlet

coach outlet

prada shoes

true religion outlet

oakley sunglasses wholesale

michael kors outlet

ugg boots

cheap nhl jerseys

moncler outlet

canada goose jackets

canada goose outlet

ecco shoes

true religion outlet

coach factory outlet

coach outlet store online

hermes outlet

chicago blackhawks jerseys

canada goose coats

herve leger outlet

ray ban sunglasses

canada goose jackets

air jordan 4

ralph lauren uk

michael kors outlet online

canada goose outlet

canada goose jackets

birkenstock sandals

ray ban sunglasses

ugg outlet

cleveland cavaliers jersey

air max 90

louboutin shoes

uggs outlet

ugg outlet

fred perry polo shirts

christian louboutin outlet

ugg outlet

nike trainers

longchamp outlet

true religion jeans

kate spade outlet

ugg outlet

ugg outlet

air max 90

longchamp handbags

oakley sunglasses

oakley sunglasses

nhl jerseys

supra shoes

links of london

canada goose jackets

polo shirts

ugg boots

canada goose outlet

polo outlet

ugg boots clearance

polo ralph lauren

canada goose outlet

christian louboutin outlet

tods outlet

true religion jeans

longchamp bags

ugg boots clearance

ugg outlet

true religion uk

converse shoes

true religion jeans

christian louboutin outlet

tory burch outlet

air max 90

valentino outlet

ugg outlet

ugg boots

ray ban sunglasses

burberry outlet

true religion jeans

ugg boots

canada goose outlet

canada goose outlet

michael kors handbags

hermes outlet

uggs outlet

ugg outlet

true religion jeans

coach outlet

fitflops sale clearance

true religion jeans

uggs outlet

kobe shoes

ray ban sunglasses

longchamp outlet

michael kors outlet

polo ralph lauren

ugg boots clearance

air max 1

fitflops

michael kors outlet

moncler outlet

canada goose black friday

cheap jordans

canada goose jackets

kate spade outlet

air huarache

nike blazer pas cher

michael kors outlet

futbol baratas

christian louboutin outlet

michael kors outlet

mulberry handbags

longchamp solde

coach factory outlet

yeezy boost

ray-ban sunglasses

swarovski outlet

uggs

michael kors

oakley sunglasses

uggs outlet

ugg outlet

moncler jackets

ralph lauren polo

michael kors outlet

ray ban sunglasses

mulberry handbags

coach outlet

yeezy boost 350

cheap mlb jerseys

coach outlet online

uggs outlet

ferragamo outlet

michael kors handbags

nike air max

burberry outlet

giuseppe zanotti outlet

lakers jerseys

soccer jerseys

cheap jerseys

michael kors uk

coach handbags

oakley sunglasses

longchamp solde

coach outlet online

michael kors handbags

coach factory outlet

mulberry outlet

polo outlet

longchamp handbags

ugg outlet

true religion outlet

nba jerseys

coach outlet online

ray ban sunglasses

swarovski outlet

ugg outlet

asics shoes

pandora jewelry

true religion jeans

michael kors handbags

nike factory outlet

ugg cyber monday

ugg outlet

coach canada

mbt shoes

ralph lauren polo

coach outlet

longchamp handbags

prada sunglasses

coach outlet online

ugg boots

ferragamo shoes

michael kors outlet online

canada goose jackets

canada goose parka

uggs outlet

coach outlet

ralph lauren polo

air max uk

bottega veneta outlet

polo outlet

20171118caihuali

Re: XMacro

f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62 f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62f62