rev |
line source |
al@592
|
1 <!DOCTYPE html>
|
al@598
|
2 <html xmlns="http://www.w3.org/1999/xhtml" lang="ru">
|
al@598
|
3 <head>
|
al@592
|
4 <meta charset="utf-8" />
|
al@592
|
5 <title>Документация CookUtils</title>
|
al@598
|
6 <link rel="stylesheet" type="text/css" href="../slitaz-doc.css" />
|
al@598
|
7 <script type="text/javascript" src="../slitaz-doc.js"></script>
|
al@592
|
8 </head>
|
al@592
|
9 <body>
|
al@598
|
10
|
al@598
|
11 <header>
|
al@592
|
12 <h1>Документация CookUtils</h1>
|
al@598
|
13 </header>
|
al@592
|
14
|
al@592
|
15 <!-- Start content -->
|
al@592
|
16 <div id="content">
|
al@592
|
17
|
al@592
|
18 <h2>Cook и Cooker в SliTaz</h2>
|
al@592
|
19
|
al@592
|
20 <p>Пакет CookUtils в SliTaz содержит утилиты, которые помогут вам собрать пакеты
|
al@592
|
21 SliTaz. Они просты в использовании и изучении, быстрые и легковесные. Вы сможете
|
al@592
|
22 создавать пакеты SliTaz при помощи всего нескольких команд. В состав CookUtils
|
al@592
|
23 входят утилита cook («повар») и <a href="#cooker">Cooker</a> («плита»).</p>
|
al@592
|
24
|
al@592
|
25 <p>Cook компилирует исходный код и создает пакет, ведет журнал и проверяет
|
al@592
|
26 качество рецепта и пакета. Cooker — это сборочный бот, обладающий большей
|
al@592
|
27 автоматизацией, он может использоваться в качестве интерфейса для cook,
|
al@592
|
28 поскольку он имеет CGI/веб-интерфейс, позволяющий просматривать журналы cook в
|
al@592
|
29 приятном цветном виде. Cook и Cooker используют одни и те же файлы баз данных и
|
al@592
|
30 wok, они оба используют списки <a href="#blocked">заблокированных</a> и
|
al@592
|
31 испорченных пакетов и т.п.</p>
|
al@592
|
32
|
al@592
|
33 <p>Для получения технической информации (стиль кодирования и т.д.), обратитесь к
|
al@592
|
34 README, находящемуся в исходниках, либо в папке /usr/share/doc/cookutils.</p>
|
al@592
|
35
|
al@592
|
36
|
al@592
|
37 <h3>Использование cook</h3>
|
al@592
|
38
|
al@592
|
39 <p>Cook содержит небольшую встроенную справку по использованию, которую можно
|
al@592
|
40 отобразить командой <b>usage</b>. Также он имеет несколько параметров для
|
al@592
|
41 выполнения специальных задач над пакетами, как перед приготовлением, так и после
|
al@592
|
42 него. Итак, чтобы получить справку по использованию:</p>
|
al@592
|
43
|
al@592
|
44 <pre># cook <b>usage</b></pre>
|
al@592
|
45
|
al@592
|
46
|
al@592
|
47 <h3>Краткая инструкция</h3>
|
al@592
|
48
|
al@592
|
49 <p>Первое, что вам нужно сделать, прежде чем начнете собирать пакеты — настроить
|
al@592
|
50 окружение. Есть два рекомендованых способа работы: собирать непосредственно на
|
al@592
|
51 хосте или собирать в изолированном chroot-окружении (для защиты хоста). Если вы
|
al@592
|
52 хотите работать в изолированном окружении, вы можете установить и использовать
|
al@592
|
53 Tazdev для создания окружения и переключения на него:</p>
|
al@592
|
54
|
al@592
|
55 <pre># tazdev gen-chroot && tazdev chroot</pre>
|
al@592
|
56
|
al@592
|
57 <p>По умолчанию Tazdev создает изолированное окружение в
|
al@592
|
58 /home/slitaz/cooking/chroot, но вы можете указать другой путь в параметре:</p>
|
al@592
|
59
|
al@592
|
60 <pre>
|
al@592
|
61 # tazdev gen-chroot <i>/home/slitaz/4.0/chroot</i>
|
al@592
|
62 # tazdev chroot <i>/home/slitaz/4.0/chroot</i>
|
al@592
|
63 </pre>
|
al@592
|
64
|
al@592
|
65 <p>Расположение изолированного окружения не важно, ведь когда вы будете
|
al@592
|
66 находиться в нём, вы будете использовать стандартные пути SliTaz, такие как
|
al@592
|
67 /home/slitaz/wok для папки wok и /home/slitaz/log для всех журналов cook. Как
|
al@592
|
68 обычно, вы можете вывести справку об использовании tazdev при помощи команды:</p>
|
al@592
|
69
|
al@592
|
70 <pre># tazdev usage</pre>
|
al@592
|
71
|
al@592
|
72 <p>При использовании изолированного окружения есть две специальные папки,
|
al@592
|
73 смонтированные с параметром bind: src и packages. Исходники всех пакетов
|
al@592
|
74 по умолчанию сохраняются в /home/slitaz/src; эта папка монтируется в chroot для
|
al@592
|
75 того, чтобы утилиты могли ее использовать. Этот метод позволяет обмениваться
|
al@592
|
76 исходниками между несколькими изолированными окружениями, например, одно
|
al@592
|
77 стабильное, а другое нестабильное. Папка с готовыми пакетами по умолчанию
|
al@592
|
78 находится в /home/slitaz/<em>версия</em>/packages, вне изолированного окружения;
|
al@592
|
79 пакеты здесь находятся в безопасности в случае удаления chroot по ошибке.</p>
|
al@592
|
80
|
al@592
|
81
|
al@592
|
82 <h3>Приступая к работе</h3>
|
al@592
|
83
|
al@592
|
84 <p>Итак, вы решили, как вы хотите работать, теперь давайте настроим окружение
|
al@592
|
85 cook. Cook использует конфигурационный файл cook.conf, если вы хотите
|
al@592
|
86 использовать собственные пути для папок и файлов SliTaz, вам придется изменить
|
al@592
|
87 его. Установка создаст некоторые папки и файлы для отслеживания работы и ошибок,
|
al@592
|
88 все файлы являются простыми текстовыми файлами, которые можно открыть в любом
|
al@592
|
89 текстовом редакторе. Чтобы подготовить окружение:</p>
|
al@592
|
90
|
al@592
|
91 <pre># cook setup</pre>
|
al@592
|
92
|
al@592
|
93 <p>Команда setup может иметь параметр --wok, который позволяет получить копию
|
al@592
|
94 wok SliTaz при настройке окружения cook. Даже если вы еще не являетесь
|
al@592
|
95 официальным разработчиком, вы можете получить копию wok и использовать
|
al@592
|
96 существующие пакеты в качестве примера для создания собственных. Для настройки
|
al@592
|
97 и клонирования wok по умолчанию (версии cooking) или версии undigest:</p>
|
al@592
|
98
|
al@592
|
99 <pre>
|
al@592
|
100 # cook setup --wok
|
al@592
|
101 # cook setup --undigest
|
al@592
|
102 </pre>
|
al@592
|
103
|
al@592
|
104
|
al@592
|
105 <h3>Проверка окружения</h3>
|
al@592
|
106
|
al@592
|
107 <p>Cook понимает команду test, по которой он создаст пакет и приготовит его.
|
al@592
|
108 Это позволяет определить, работает ли окружение и является примером пакета
|
al@592
|
109 с рецептом. Созданный фиктивный пакет называется «cooktest», его можно удалить
|
al@592
|
110 после тестирования. Для приготовления тестового пакета:</p>
|
al@592
|
111
|
al@592
|
112 <pre># cook test</pre>
|
al@592
|
113
|
al@592
|
114
|
al@592
|
115 <h3>Создание и приготовление</h3>
|
al@592
|
116
|
al@592
|
117 <p>Если ваша среда настроена правильно, вы можете приступить к созданию
|
al@592
|
118 и компиляции пакетов SliTaz из вашего wok. Чтобы создать новый пакет с пустым
|
al@592
|
119 рецептом (вы также можете создавать рецепты в интерактивном режиме):</p>
|
al@592
|
120
|
al@592
|
121 <pre>
|
al@592
|
122 # cook new имя-пакета
|
al@592
|
123 # cook new имя-пакета --interactive
|
al@592
|
124 </pre>
|
al@592
|
125
|
al@592
|
126 <p>Вы только что создали новый пакет, теперь вам нужно отредактировать рецепт
|
al@592
|
127 в вашем любимом текстовом редакторе. Когда рецепт будет готов, вы можете
|
al@592
|
128 приготовить его:</p>
|
al@592
|
129
|
al@592
|
130 <pre># cook имя-пакета</pre>
|
al@592
|
131
|
al@592
|
132 <p>Если все прошло успешно, то вы найдете свой пакет в папке $SLITAZ/packages,
|
al@592
|
133 а все созданные файлы — в $SLITAZ/wok/имя-пакета.</p>
|
al@592
|
134
|
al@592
|
135
|
al@592
|
136 <h3>Приготовление с установкой</h3>
|
al@592
|
137
|
al@592
|
138 <p>Если вы хотите приготовить и установить пакет одной командой:</p>
|
al@592
|
139
|
al@592
|
140 <pre># cook имя-пакета --install</pre>
|
al@592
|
141
|
al@592
|
142
|
al@592
|
143 <h3>Получение исходников</h3>
|
al@592
|
144
|
al@592
|
145 <p>Если вам нужно загрузить только исходники пакета, не создавая его, вы можете
|
al@592
|
146 использовать опцию --getsrc как показано ниже:</p>
|
al@592
|
147
|
al@592
|
148 <pre># cook имя-пакета --getsrc</pre>
|
al@592
|
149
|
al@592
|
150
|
al@592
|
151 <h3>Очистка пакетов</h3>
|
al@592
|
152
|
al@592
|
153 <p>После компиляции и упаковки в wok по-прежнему остаются файлы, которые
|
al@592
|
154 занимают место на диске. Для очистки выбранного пакета:</p>
|
al@592
|
155
|
al@592
|
156 <pre># cook имя-пакета --clean</pre>
|
al@592
|
157
|
al@592
|
158 <p>Вы также можете очистить сразу целый wok. Если решите сохранить связанные
|
al@592
|
159 с SliTaz файлы, вы можете удалить только исходники:</p>
|
al@592
|
160
|
al@592
|
161 <pre>
|
al@592
|
162 # cook clean-wok
|
al@592
|
163 # cook clean-src
|
al@592
|
164 </pre>
|
al@592
|
165
|
al@592
|
166
|
al@592
|
167 <h3>Поиск</h3>
|
al@592
|
168
|
al@592
|
169 <p>Cook поддерживает простую функцию поиска пакета в wok. Поиск использует grep
|
al@592
|
170 и поддерживает регулярные выражения:</p>
|
al@592
|
171
|
al@592
|
172 <pre># cook search busybox</pre>
|
al@592
|
173
|
al@592
|
174
|
al@592
|
175 <h3>База данных пакетов</h3>
|
al@592
|
176
|
al@592
|
177 <p>Cook может создать список пакетов в wok, а также создать соответствующий
|
al@592
|
178 список пакетов для TazPkg. Это позволяет легко создавать локальный репозиторий
|
al@592
|
179 пакетов, а также используется для создания официального списка пакетов SliTaz,
|
al@592
|
180 находящихся на зеркалах. Для просмотра текущего wok (вам не нужно быть
|
al@592
|
181 суперпользователем):</p>
|
al@592
|
182
|
al@592
|
183 <pre>$ cook list-wok</pre>
|
al@592
|
184
|
al@592
|
185 <p>При создании базы данных пакетов Cook проверит наличие редакций (flavors) в
|
al@592
|
186 /home/slitaz/flavors и при их наличии укомплектует все редакции новейшими
|
al@592
|
187 пакетами из списка доступных. Чтобы создать список пакетов и файлы редакций
|
al@592
|
188 Live:</p>
|
al@592
|
189
|
al@592
|
190 <pre># cook pkgdb</pre>
|
al@592
|
191
|
al@592
|
192
|
al@592
|
193 <h3 id="cooker">Cooker</h3>
|
al@592
|
194
|
al@592
|
195 <p>Cooker является сборочным ботом, он предназначен в первую очередь для
|
al@592
|
196 проверки изменений в wok, создания упорядоченного списка приготовления, и
|
al@592
|
197 приготовления изменившихся пакетов. Он также может быть использован в качестве
|
al@592
|
198 интерфейса для cook, так как они оба используют одинаковые файлы. Cooker может
|
al@592
|
199 быть также использован для приготовления большого списка пакетов за один прием,
|
al@592
|
200 такого, как, например, все пакеты редакции (flavor). Cooker имеет хороший
|
al@592
|
201 CGI/веб-интерфейс, который работает по умолчанию на любой системе SliTaz,
|
al@592
|
202 поскольку она обеспечивает поддержку CGI с помощью веб-сервера HTTPD BusyBox.</p>
|
al@592
|
203
|
al@592
|
204 <p>Cooker содержит небольшую встроенную справку об использовании и о коротких
|
al@592
|
205 командах. Например, чтобы отобразить информацию об использовании:</p>
|
al@592
|
206
|
al@592
|
207 <pre>
|
al@592
|
208 # cooker usage
|
al@592
|
209 # cooker -u
|
al@592
|
210 </pre>
|
al@592
|
211
|
al@592
|
212
|
al@592
|
213 <h3>Настройка Cooker</h3>
|
al@592
|
214
|
al@592
|
215 <p>Так же как и Cook, Cooker нуждается в рабочей среде, прежде чем начать его
|
al@592
|
216 использовать. Основное отличие от среды Cook в том, что Cooker требует два wok.
|
al@592
|
217 Один чистый wok с Hg, в качестве справочного, а другой — ваш экспериментальный
|
al@592
|
218 сборочный wok. В таком случае можно будет легко сравнить между собой оба wok
|
al@592
|
219 и определить изменения. Если у вас уже есть окружение Cook, вам необходимо
|
al@592
|
220 переместить ваш wok до настройки Cooker, или он будет жаловаться. Программа
|
al@592
|
221 установки также установит набор пакетов для разработки, которые могут быть
|
al@592
|
222 настроены в конфигурационном файле cook.conf и переменной SETUP_PKGS.
|
al@592
|
223 Для настройки окружения Cooker:</p>
|
al@592
|
224
|
al@592
|
225 <pre># cooker setup</pre>
|
al@592
|
226
|
al@592
|
227 <p>Если всё прошло хорошо, то теперь у вас есть 2 wok, установлены базовые
|
al@592
|
228 пакеты разработки и созданы все необходимые файлы. Поведение по умолчанию
|
al@592
|
229 заключается в проверке коммитов, вы можете запустить тест:</p>
|
al@592
|
230
|
al@592
|
231 <pre># cooker</pre>
|
al@592
|
232
|
al@592
|
233
|
al@592
|
234 <h3>Работа с Cooker</h3>
|
al@592
|
235
|
al@592
|
236 <p>Опять же, теперь есть два способа работы: внести изменения в чистый wok Hg
|
al@592
|
237 и запустить Cooker без аргументов, либо готовить пакеты вручную. Cooker
|
al@592
|
238 позволяет приготовить одиночный пакет, или все пакеты определеной категории,
|
al@592
|
239 или всю редакцию (flavor) целиком. Вы также можете попытаться приготовить все
|
al@592
|
240 не приготовленные пакеты, но знайте, что Cooker не был рассчитан для обработки
|
al@592
|
241 тысяч пакетов.</p>
|
al@592
|
242
|
al@592
|
243 <p>Чтобы приготовить одиночный пакет, то же самое, что дает команда «cook
|
al@592
|
244 имя_пакета», но с несколькими журналами:</p>
|
al@592
|
245
|
al@592
|
246 <pre># cooker pkg имя-пакета</pre>
|
al@592
|
247
|
al@592
|
248 <p>Чтобы приготовить более одного пакета за раз, у вас есть различные решения.
|
al@592
|
249 Вы можете использовать существующий список, такой как используемый для редакции
|
al@592
|
250 Live, вы также можете использовать собственный список, перечислив имена пакетов
|
al@592
|
251 по одному на строку. Наконец, вы можете приготовить все пакеты категории.</p>
|
al@592
|
252
|
al@592
|
253 <pre>
|
al@592
|
254 # cooker flavor [имя]
|
al@592
|
255 # cooker list [/путь/к/списку]
|
al@592
|
256 # cooker cat [категория]
|
al@592
|
257 </pre>
|
al@592
|
258
|
al@592
|
259 <p>Cooker позволяет также повторно приготовить указанную ревизию Hg. Это будет
|
al@592
|
260 полезно, если во время приготовления пакетов сборочный бот был прерван новым
|
al@592
|
261 коммитом, вы всё равно имеете возможность готовить пакеты вручную:</p>
|
al@592
|
262
|
al@592
|
263 <pre># cooker rev 9496</pre>
|
al@592
|
264
|
al@592
|
265
|
al@592
|
266 <h3 id="blocked">Заблокированные пакеты</h3>
|
al@592
|
267
|
al@592
|
268 <p>Cook и Cooker работают со списком заблокированных пакетов, которые не будут
|
al@592
|
269 готовиться даже в случае получения коммита или, если они будут упомянуты в
|
al@592
|
270 списке приготовления. Это полезное свойство сборочного бота Cooker. При
|
al@592
|
271 блокировании и разблокировании пакетов, вы можете добавить свои примечания.
|
al@592
|
272 Пример блокирования пакетов:</p>
|
al@592
|
273
|
al@592
|
274 <pre>
|
al@592
|
275 # cook имя_пакета --block
|
al@592
|
276 # cooker block имя_пакета
|
al@592
|
277 # cooker -n "Примечание о блокировании имя_пакета"
|
al@592
|
278 </pre>
|
al@592
|
279
|
al@592
|
280 <p>Список заблокированных пакетов также отображается в веб-интерфейсе Cooker.
|
al@592
|
281 Чтобы разблокировать пакет, используйте команду unblock или запустите Cook
|
al@592
|
282 с опцией --unblock:</p>
|
al@592
|
283
|
al@592
|
284 <pre>
|
al@592
|
285 # cooker unblock имя_пакета
|
al@592
|
286 # cook имя_пакета --unblock
|
al@592
|
287 </pre>
|
al@592
|
288
|
al@592
|
289
|
al@592
|
290 <h3>CGI/веб-интерфейс Cooker</h3>
|
al@592
|
291
|
al@592
|
292 <p>Чтобы просмотреть наглядные файлы журналов, проследить порядок работы,
|
al@592
|
293 найти ошибки, вы можете использовать веб-интерфейс Cooker, который по умолчанию
|
al@592
|
294 находится в папке /var/www/cooker. Если вы не используете изолированное
|
al@592
|
295 окружение и веб-сервер Busybox HTTPD запущен, то веб-интерфейс будет работать
|
al@592
|
296 без дополнительных настроек и будет доступен по адресу: <a
|
al@592
|
297 href="http://localhost/cooker/cooker.cgi">http://localhost/cooker/cooker.cgi</a>
|
al@592
|
298 </p>
|
al@592
|
299
|
al@592
|
300 <p>Если вы используете изолированную среду, вы должны также установить Cookutils
|
al@592
|
301 на вашу хост-машину и изменить путь в переменной SLITAZ. Обычно изолированная
|
al@592
|
302 среда находится по пути:</p>
|
al@592
|
303
|
al@592
|
304 <pre>/home/slitaz/cooking/chroot</pre>
|
al@592
|
305
|
al@592
|
306 <p>Измените /etc/slitaz/cook.conf следующим образом:</p>
|
al@592
|
307
|
al@592
|
308 <pre>SLITAZ="/home/slitaz/cooking/chroot/home/slitaz"</pre>
|
al@592
|
309
|
al@592
|
310 <p>Примечание: не обязательно устанавливать Cookutils на вашу хост-машину, чтобы
|
al@592
|
311 использовать веб-интерфейс. Если вы используете Lighttpd, вы можете также
|
al@592
|
312 скопировать файлы cooker.cgi и style.css, например, в папку ~/Public
|
al@592
|
313 и использовать собственный cook.conf. Преимущество установки Cookutils на
|
al@592
|
314 хост-машину в получении регулярных обновлений через менеджер пакетов TazPkg.
|
al@592
|
315 Скажем, вы клонировали или загрузили Cookutils:</p>
|
al@592
|
316
|
al@592
|
317 <pre>
|
al@592
|
318 $ cp -a cookutils/web ~/Public/cgi-bin/cooker
|
al@592
|
319 $ cp -f cookutils/cook.conf ~/Public/cgi-bin/cooker
|
al@592
|
320 </pre>
|
al@592
|
321
|
al@592
|
322 <p>Отредактируйте конфигурационный файл ~/Public/cgi-bin/cooker/cook.conf,
|
al@592
|
323 указав в переменной SLITAZ нужный путь, и это всё!</p>
|
al@592
|
324
|
al@592
|
325
|
al@592
|
326 <h3>Заметки (Cooknotes)</h3>
|
al@592
|
327
|
al@592
|
328 <p>Функция Cooknotes позволяет записывать небольшие личные заметки о сборке
|
al@592
|
329 пакетов и полезна для совместной работы. Cooknotes была написана, чтобы
|
al@592
|
330 сопровождающие сборочного бота Cooker в SliTaz могли делиться заметками между
|
al@592
|
331 собой и с другими участниками. Cooker может блокировать сборку пакета или
|
al@592
|
332 пакеты можно пересобрать вручную, например, неплохо обратите внимание, когда
|
al@592
|
333 пакет был заблокирован, чтобы сопровождающий знал, почему администратор сделал
|
al@592
|
334 это. Cooknotes отображаются в веб-интерфейсе и могут быть проверены в командной
|
al@592
|
335 строке:</p>
|
al@592
|
336
|
al@592
|
337 <pre>
|
al@592
|
338 # cooker note "Заблокирован имя_пакета из-за высокой нагрузки на процессор"
|
al@592
|
339 # cooker notes
|
al@592
|
340 </pre>
|
al@592
|
341
|
al@592
|
342
|
al@592
|
343 <h3>Cooker в качестве сборочного бота</h3>
|
al@592
|
344
|
al@592
|
345 <p>Cooker был задуман как сборочный бот для SliTaz, это означает, что он следит
|
al@592
|
346 за обновлениями двух wok на Hg, находит различия и готовит все необходимые
|
al@592
|
347 пакеты. Безопасный и прозрачный способ запуска Cooker в качестве сборочного бота
|
al@592
|
348 с помощью cron подразумевает использование изолированной среды, но при
|
al@592
|
349 необходимости он может работать и непосредственно на хосте.</p>
|
al@592
|
350
|
al@592
|
351 <p>Для автоматического запуска Cooker вы должны использовать cron из
|
al@592
|
352 изолированной среды и добавить одну строку в корень crontabs в папке
|
al@592
|
353 /var/spool/cron/crontabs. Скажем, вы хотите, чтобы Cooker запускался каждые два
|
al@592
|
354 часа:</p>
|
al@592
|
355
|
al@592
|
356 <pre>* */2 * * * /usr/bin/cooker</pre>
|
al@592
|
357
|
al@592
|
358
|
al@592
|
359 <h3>Запуск Cooker BB при загрузке системы</h3>
|
al@592
|
360
|
al@592
|
361 <p>Окружение Cooker и задачи cron могут быть автоматически запущены при
|
al@592
|
362 загрузке. Вы должны установить пакет cookutils-daemon на хост и использовать
|
al@592
|
363 стандартную установку SliTaz, чтобы заставить его работать должным образом
|
al@592
|
364 (приготовление идет в /home/slitaz/cooking). Запущенная служба при необходимости
|
al@592
|
365 смонтирует любую виртуальную файловую систему, так же как и папки с исходниками
|
al@592
|
366 и пакетами. Исходники в /home/slitaz/src связаны с изолированной средой, чтобы
|
al@592
|
367 вы могли поделиться исходниками пакетов между несколькими версиями (стабильная,
|
al@592
|
368 cooking, undigest). Установите пакет, если он еще не установлен:</p>
|
al@592
|
369
|
al@592
|
370 <pre># tazpkg get-install cookutils-daemon</pre>
|
al@592
|
371
|
al@592
|
372 <p>Для запуска службы вам необходимо иметь файл описания задачи cron в корне
|
al@592
|
373 изолированной среды, эта служба работает так же, как и все другие в системы и
|
al@592
|
374 может управляться командами:</p>
|
al@592
|
375
|
al@592
|
376 <pre># /etc/init.d/cooker [start|stop|restart]</pre>
|
al@592
|
377
|
al@592
|
378 <!-- End content -->
|
al@592
|
379 </div>
|
al@592
|
380
|
al@598
|
381 <footer>
|
pascal@627
|
382 Авторское право © 2011–<span class="year"></span> <a href="http://www.slitaz.org/">SliTaz GNU/Linux</a>
|
al@598
|
383 </footer>
|
al@592
|
384
|
al@592
|
385 </body>
|
al@592
|
386 </html>
|