summaryrefslogtreecommitdiff
path: root/src/event.h (plain)
blob: 7b699a3dd139a9d9b24fe0161483772f83951485
1/*
2 * libzvbi -- Events
3 *
4 * Copyright (C) 2000, 2001, 2002 Michael H. Schimek
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA.
20 */
21
22/* $Id: event.h,v 1.14 2008/02/19 00:35:15 mschimek Exp $ */
23
24#ifndef EVENT_H
25#define EVENT_H
26
27#include "bcd.h"
28
29#ifndef VBI_DECODER
30#define VBI_DECODER
31typedef struct vbi_decoder vbi_decoder;
32#endif
33
34/* Public */
35
36#include <inttypes.h>
37
38/**
39 * @addtogroup Event Events
40 * @ingroup HiDec
41 *
42 * Typically the transmission of VBI data like a Teletext or Closed
43 * Caption page spans several VBI lines or even video frames. So internally
44 * the data service decoder maintains caches accumulating data. When a page
45 * or other object is complete it calls the respective event handler to
46 * notify the application.
47 *
48 * Clients can register any number of handlers needed, also different
49 * handlers for the same event. They will be called in the order registered
50 * from the vbi_decode() function. Since they block decoding, they should
51 * return as soon as possible. The event structure and all data
52 * pointed to from there must be read only. The data is only valid until
53 * the handler returns.
54 */
55
56/**
57 * @ingroup Event
58 * @brief Unique network id (a libzvbi thing).
59 *
60 * 0 = unknown network, bit 31 reserved for preliminary nuids.
61 * Other network codes are arbitrary.
62 */
63typedef unsigned int vbi_nuid;
64
65/**
66 * @ingroup Event
67 * @brief Network description.
68 *
69 * All strings are ISO 8859-1 encoded (yes that's stupid, sorry)
70 * and @c NUL terminated. Prepare for empty strings. Read only.
71 */
72typedef struct {
73 vbi_nuid nuid;
74
75 /**
76 * Name of the network from XDS or from a table lookup of
77 * CNIs in Teletext packet 8/30 or VPS.
78 */
79 signed char name[64];
80
81 /**
82 * Network call letters, from XDS. Empty if unknown or
83 * not applicable.
84 */
85 signed char call[40];
86
87 /**
88 * Tape delay in minutes, from XDS. Zero if unknown or
89 * not applicable.
90 **/
91 int tape_delay;
92
93 /**
94 * The European Broadcasting Union (EBU) maintains several tables
95 * of Country and Network Identification (CNI) codes. CNIs of type
96 * VPS, 8/30-1 and 8/30-2 can be used to identify networks during
97 * a channel scan.
98 *
99 * This field contains the CNI of the network found in a VPS
100 * packet. It can be zero if unknown or CNI's are not applicable.
101 * Note VPS has room for only 4 lsb of the country code (0xCNN).
102 *
103 * For example ZDF: 0xDC2.
104 */
105 int cni_vps;
106
107 /**
108 * CNI of the network from Teletext packet 8/30 format 1,
109 * zero if unknown or not applicable. The country code is
110 * stored in the MSB, the network code in the LSB (0xCCNN).
111 * Note these CNIs may use different country and network codes
112 * than the PDC (VPS, 8/30-2) CNIs.
113 *
114 * For example BBC1: 0x447F, ZDF: 0x4902.
115 */
116 int cni_8301;
117
118 /**
119 * CNI of the network from Teletext packet 8/30 format 2,
120 * zero if unknown or not applicable. The country code is
121 * stored in the MSB, the network code in the LSB (0xCCNN).
122 *
123 * For example BBC1: 0x2C7F, ZDF: 0x1DC2.
124 */
125 int cni_8302;
126
127 int reserved;
128
129 /** Private. */
130 int cycle;
131} vbi_network;
132
133/*
134 * Link
135 */
136
137/**
138 * @ingroup Event
139 * @brief Link type.
140 */
141typedef enum {
142 /**
143 * vbi_resolve_link() may return a link of this type on failure.
144 */
145 VBI_LINK_NONE = 0,
146 /**
147 * Not really a link, only vbi_link->name will be set. (Probably
148 * something like "Help! Help! The station is on fire!")
149 */
150 VBI_LINK_MESSAGE,
151 /**
152 * Points to a Teletext page, vbi_link->pgno and vbi_link->subno,
153 * eventually vbi_link->nuid and a descriptive text in vbi_link->name.
154 */
155 VBI_LINK_PAGE,
156 /**
157 * Also a Teletext page link, but this one is used exclusively
158 * to link subpages of the page containing the link.
159 */
160 VBI_LINK_SUBPAGE,
161 /**
162 * vbi_link->url is a HTTP URL (like "http://zapping.sf.net"),
163 * eventually accompanied by a descriptive text vbi_link->name.
164 */
165 VBI_LINK_HTTP,
166 /**
167 * vbi_link->url is a FTP URL (like "ftp://foo.bar.com/baz"),
168 * eventually accompanied by a descriptive text vbi_link->name.
169 */
170 VBI_LINK_FTP,
171 /**
172 * vbi_link->url is an e-mail address (like "mailto:foo@bar"),
173 * eventually accompanied by a descriptive text vbi_link->name.
174 */
175 VBI_LINK_EMAIL,
176 /** Is a trigger link id. Not useful, just ignore. */
177 VBI_LINK_LID,
178 /** Is a SuperTeletext link, ignore. */
179 VBI_LINK_TELEWEB
180} vbi_link_type;
181
182/**
183 * @ingroup Event
184 * @brief ITV link type.
185 *
186 * Some ITV (WebTV, ATVEF) triggers include a type id intended
187 * to filter relevant information. The names should speak for
188 * themselves. EACEM triggers always have type @c VBI_WEBLINK_UNKNOWN.
189 **/
190typedef enum {
191 VBI_WEBLINK_UNKNOWN = 0,
192 VBI_WEBLINK_PROGRAM_RELATED,
193 VBI_WEBLINK_NETWORK_RELATED,
194 VBI_WEBLINK_STATION_RELATED,
195 VBI_WEBLINK_SPONSOR_MESSAGE,
196 VBI_WEBLINK_OPERATOR
197} vbi_itv_type;
198
199/**
200 * @ingroup Event
201 *
202 * General purpose link description for ATVEF (ITV, WebTV in the
203 * United States) and EACEM (SuperTeletext et al in Europe) triggers,
204 * Teletext TOP and FLOF navigation, and for links "guessed" by
205 * libzvbi from the text (e. g. page numbers and URLs). Usually
206 * not all fields will be used.
207 */
208typedef struct vbi_link {
209 /**
210 * See vbi_link_type.
211 */
212 vbi_link_type type;
213 /**
214 * Links can be obtained two ways, via @ref VBI_EVENT_TRIGGER,
215 * then it arrived either through the EACEM or ATVEF transport
216 * method as flagged by this field. Or it is a navigational link
217 * returned by vbi_resolve_link(), then this field does not apply.
218 */
219 vbi_bool eacem;
220 /**
221 * Some descriptive text, Latin-1, possibly blank.
222 */
223 signed char name[80];
224 signed char url[256];
225 /**
226 * A piece of ECMA script (Javascript), this may be
227 * used on WebTV or SuperTeletext pages to trigger some action.
228 * Usually blank.
229 */
230 signed char script[256];
231 /**
232 * Teletext page links (no Closed Caption counterpart) can
233 * can actually reach across networks. That happens for example
234 * when vbi_resolve_link() picked up a link on a page after we
235 * switch away from that channel, or with EACEM triggers
236 * deliberately pointing to a page on another network (sic!).
237 * So the network id (if known, otherwise 0) is part of the
238 * page number. See vbi_nuid.
239 */
240 vbi_nuid nuid;
241 /**
242 * @a pgno and @a subno Teletext page number, see vbi_pgno, vbi_subno.
243 */
244 vbi_pgno pgno;
245 vbi_subno subno;
246 /**
247 * The time in seconds and fractions since
248 * 1970-01-01 00:00 when the link should no longer be offered
249 * to the user, similar to a HTTP cache expiration date.
250 */
251 double expires;
252 /**
253 * See vbi_itv_type. This field applies only to
254 * ATVEF triggers, is otherwise @c VBI_WEBLINK_UNKNOWN.
255 */
256 vbi_itv_type itv_type;
257 /**
258 * Trigger priority. 0 = emergency, should never be
259 * blocked. 1 or 2 = "high", 3 ... 5 = "medium", 6 ... 9 =
260 * "low". The default is 9. Apart of filtering triggers, this
261 * is also used to determine at which priority multiple links
262 * should be presented to the user. This field applies only to
263 * EACEM triggers, is otherwise 9.
264 */
265 int priority;
266 /**
267 * Open the target without user confirmation. (Supposedly
268 * this flag will be used to trigger scripts, not to open pages,
269 * but I have yet to see such a trigger.)
270 */
271 vbi_bool autoload;
272} vbi_link;
273
274/*
275 * Aspect ratio information.
276 */
277
278/**
279 * @ingroup Event
280 * @brief Open subtitle information.
281 *
282 * Open because they have been inserted into the picture, as
283 * opposed to closed subtitles (closed caption) encoded in the vbi.
284 */
285typedef enum {
286 VBI_SUBT_NONE, /**< No open subtitles. */
287 VBI_SUBT_ACTIVE, /**< Inserted in active picture. */
288 VBI_SUBT_MATTE, /**< Inserted in upper or lower letterbox bar. */
289 VBI_SUBT_UNKNOWN /**< Presence of open subtitles unknown. */
290} vbi_subt;
291
292/**
293 * @ingroup Event
294 * @brief Information about the picture aspect ratio and open subtitles.
295 *
296 * This is available via @ref VBI_EVENT_ASPECT.
297 */
298typedef struct {
299 /**
300 * @a first_line and @a last_line, inclusive, describe the bounds of active
301 * video, i. e. without the black bars in letterbox mode. These are
302 * <em>first field</em> line numbers according to the ITU-R line
303 * numbering scheme, see vbi_sliced. For example PAL 23 ... 310 (288 lines),
304 * NTSC 22 ... 262 (240 lines).
305 */
306 int first_line;
307 int last_line;
308 /**
309 * The picture aspect ratio in <em>anamorphic</em> mode,
310 * 16/9 for example. Normal or letterboxed video has aspect ratio 1/1.
311 */
312 double ratio;
313 /**
314 * @c TRUE when the source is known to be film transferred to
315 * video, as opposed to interlaced video from a video camera. (This is
316 * actually a helper flag for PALPlus decoders, but it may assist
317 * deinterlacers too.)
318 */
319 vbi_bool film_mode;
320 /**
321 * Describes how subtitles are inserted into the picture,
322 * see vbi_subt for details.
323 */
324 vbi_subt open_subtitles;
325} vbi_aspect_ratio;
326
327/*
328 * Program Info
329 *
330 * ATTN this is new stuff and subject to change
331 */
332
333/**
334 * @ingroup Event
335 * @brief Program rating source.
336 *
337 * If program rating information is available (also known in the
338 * U. S. as V-Chip data), this describes which rating scheme is
339 * being used: U. S. film, U. S. TV, Canadian English or French TV.
340 * You can convert the rating code to a string with
341 * vbi_rating_string().
342 *
343 * When the scheme is @c VBI_RATING_TV_US, additionally the
344 * DLSV rating flags will be set.
345 */
346typedef enum {
347 VBI_RATING_AUTH_NONE = 0,
348 VBI_RATING_AUTH_MPAA,
349 VBI_RATING_AUTH_TV_US,
350 VBI_RATING_AUTH_TV_CA_EN,
351 VBI_RATING_AUTH_TV_CA_FR
352} vbi_rating_auth;
353
354/**
355 * @ingroup Event
356 * @name US TV rating flags
357 * @{
358 */
359#define VBI_RATING_D 0x08 /**< "sexually suggestive dialog" */
360#define VBI_RATING_L 0x04 /**< "indecent language" */
361#define VBI_RATING_S 0x02 /**< "sexual situations" */
362#define VBI_RATING_V 0x01 /**< "violence" */
363/** @} */
364
365extern const char * vbi_rating_string(vbi_rating_auth auth, int id);
366
367/**
368 * @ingroup Event
369 * @brief Program classification schemes.
370 *
371 * libzvbi understands two different program classification schemes,
372 * the EIA-608 based in the United States and the ETS 300 231 based
373 * one in Europe. You can convert the program type code into a
374 * string with vbi_prog_type_string().
375 **/
376typedef enum {
377 VBI_PROG_CLASSF_NONE = 0,
378 VBI_PROG_CLASSF_EIA_608,
379 VBI_PROG_CLASSF_ETS_300231
380} vbi_prog_classf;
381
382/**
383 * @addtogroup Event
384 * @{
385 */
386extern const char * vbi_prog_type_string(vbi_prog_classf classf, int id);
387/** @} */
388
389/**
390 * @ingroup Event
391 * @brief Type of audio transmitted on one (mono or stereo)
392 * audio track.
393 */
394/* code depends on order, don't change */
395typedef enum {
396 VBI_AUDIO_MODE_NONE = 0, /**< No sound. */
397 VBI_AUDIO_MODE_MONO, /**< Mono audio. */
398 VBI_AUDIO_MODE_STEREO, /**< Stereo audio. */
399 VBI_AUDIO_MODE_STEREO_SURROUND, /**< Surround. */
400 VBI_AUDIO_MODE_SIMULATED_STEREO, /**< ? */
401 /**
402 * Spoken descriptions of the program for the blind, on a secondary audio track.
403 */
404 VBI_AUDIO_MODE_VIDEO_DESCRIPTIONS,
405 /**
406 * Unrelated to the current program.
407 */
408 VBI_AUDIO_MODE_NON_PROGRAM_AUDIO,
409
410 VBI_AUDIO_MODE_SPECIAL_EFFECTS, /**< ? */
411 VBI_AUDIO_MODE_DATA_SERVICE, /**< ? */
412 /**
413 * We have no information what is transmitted.
414 */
415 VBI_AUDIO_MODE_UNKNOWN
416} vbi_audio_mode;
417
418/**
419 * @ingroup Event
420 *
421 * Information about the current program, preliminary.
422 */
423typedef struct vbi_program_info {
424 /*
425 * Refers to the current or next program.
426 * (No [2] to allow clients filtering current data more easily.)
427 */
428 unsigned int future : 1;
429
430 /* 01 Program Identification Number */
431
432 /* If unknown all these fields are -1 */
433 signed char month; /* 0 ... 11 */
434 signed char day; /* 0 ... 30 */
435 signed char hour; /* 0 ... 23 */
436 signed char min; /* 0 ... 59 */
437
438 /*
439 * VD: "T indicates if a program is routinely tape delayed for the
440 * Mountain and Pacific time zones."
441 */
442 signed char tape_delayed;
443
444 /* 02 Program Length */
445
446 /* If unknown all these fields are -1 */
447 signed char length_hour; /* 0 ... 63 */
448 signed char length_min; /* 0 ... 59 */
449
450 signed char elapsed_hour; /* 0 ... 63 */
451 signed char elapsed_min; /* 0 ... 59 */
452 signed char elapsed_sec; /* 0 ... 59 */
453
454 /* 03 Program name */
455
456 /* If unknown title[0] == 0 */
457 signed char title[64]; /* ASCII + '\0' */
458
459 /* 04 Program type */
460
461 /*
462 * If unknown type_classf == VBI_PROG_CLASSF_NONE.
463 * VBI_PROG_CLASSF_EIA_608 can have up to 32 tags
464 * identifying 96 keywords. Their numerical value
465 * is given here instead of composing a string for
466 * easier filtering. Use vbi_prog_type_str_by_id to
467 * get the keywords. A zero marks the end.
468 */
469 vbi_prog_classf type_classf;
470 int type_id[33];
471
472 /* 05 Program rating */
473
474 /*
475 * For details STFW for "v-chip"
476 * If unknown rating_auth == VBI_RATING_NONE
477 */
478 vbi_rating_auth rating_auth;
479 int rating_id;
480
481 /* Only valid when auth == VBI_RATING_TV_US */
482 int rating_dlsv;
483
484 /* 06 Program Audio Services */
485
486 /*
487 * BTSC audio (two independent tracks) is flagged according to XDS,
488 * Zweiton/NICAM/EIA-J audio is flagged mono/none, stereo/none or
489 * mono/mono for bilingual transmissions.
490 */
491 struct {
492 /* If unknown mode == VBI_AUDIO_MODE_UNKNOWN */
493 vbi_audio_mode mode;
494 /* If unknown language == NULL */
495 unsigned char * language; /* Latin-1 */
496 } audio[2]; /* primary and secondary */
497
498 /* 07 Program Caption Services */
499
500 /*
501 * Bits 0...7 corresponding to Caption page 1...8.
502 * Note for the current program this information is also
503 * available via vbi_classify_page().
504 *
505 * If unknown caption_services == -1, _language[] = NULL
506 */
507 int caption_services;
508 unsigned char * caption_language[8]; /* Latin-1 */
509
510 /* 08 Copy Generation Management System */
511
512 /* If unknown cgms_a == -1 */
513 int cgms_a; /* XXX */
514
515 /* 09 Aspect Ratio */
516
517 /*
518 * Note for the current program this information is also
519 * available via VBI_EVENT_ASPECT.
520 *
521 * If unknown first_line == last_line == -1, ratio == 0.0
522 */
523 vbi_aspect_ratio aspect;
524
525 /* 10 - 17 Program Description */
526
527 /*
528 * 8 rows of 0...32 ASCII chars + '\0',
529 * if unknown description[0...7][0] == 0
530 */
531 signed char description[8][33];
532} vbi_program_info;
533
534/**
535 * @addtogroup Event
536 * @{
537 */
538extern void vbi_reset_prog_info(vbi_program_info *pi);
539/** @} */
540
541/**
542 * @ingroup Event
543 * @name Event types.
544 * @{
545 */
546
547/**
548 * @anchor VBI_EVENT_
549 * No event.
550 */
551#define VBI_EVENT_NONE 0x0000
552/**
553 * The vbi decoding context is about to be closed. This event is
554 * sent by vbi_decoder_delete() and can be used to clean up
555 * event handlers.
556 */
557#define VBI_EVENT_CLOSE 0x0001
558/**
559 * The vbi decoder received and cached another Teletext page
560 * designated by ev.ttx_page.pgno and ev.ttx_page.subno.
561 *
562 * ev.ttx_page.roll_header flags the page header as suitable for
563 * rolling page numbers, e. g. excluding pages transmitted out
564 * of order.
565 *
566 * The ev.ttx_page.header_update flag is set when the header,
567 * excluding the page number and real time clock, changed since the
568 * last @c VBI_EVENT_TTX_PAGE. Note this may happen at midnight when the
569 * date string changes. The ev.ttx_page.clock_update flag is set when
570 * the real time clock changed since the last @c VBI_EVENT_TTX_PAGE (that is
571 * at most once per second). They are both set at the first
572 * @c VBI_EVENT_TTX_PAGE sent and unset while the received header
573 * or clock field is corrupted.
574 *
575 * If any of the roll_header, header_update or clock_update flags
576 * are set ev.ttx_page.raw_header is a pointer to the raw header data
577 * (40 bytes), which remains valid until the event handler returns.
578 * ev.ttx_page.pn_offset will be the offset (0 ... 37) of the three
579 * digit page number in the raw or formatted header. Allways call
580 * vbi_fetch_vt_page() for proper translation of national characters
581 * and character attributes, the raw header is only provided here
582 * as a means to quickly detect changes.
583 */
584#define VBI_EVENT_TTX_PAGE 0x0002
585/**
586 * A Closed Caption page has changed and needs visual update.
587 * The page or "CC channel" is designated by ev.caption.pgno,
588 * see vbi_pgno for details.
589 *
590 * When the client is monitoring this page, the expected action is
591 * to call vbi_fetch_cc_page(). To speed up rendering more detailed
592 * update information is provided in vbi_page.dirty, see #vbi_page.
593 * The vbi_page will be a snapshot of the status at fetch time
594 * and not event time, vbi_page.dirty accumulates all changes since
595 * the last fetch.
596 */
597#define VBI_EVENT_CAPTION 0x0004
598/**
599 * Some station/network identifier has been received or is no longer
600 * transmitted (vbi_network all zero, eg. after a channel switch).
601 * ev.network is a vbi_network object, read only. The event will not
602 * repeat*) unless a different identifier has been received and confirmed.
603 *
604 * Minimum time to identify network, when data service is transmitted:
605 * <table>
606 * <tr><td>VPS (DE/AT/CH only):</td><td>0.08 s</td></tr>
607 * <tr><td>Teletext PDC, 8/30:</td><td>2 s</td></tr>
608 * <tr><td>XDS (US only):</td><td>unknown, between 0.1x to 10x seconds</td></tr>
609 * </table>
610 *
611 * *) VPS/TTX and XDS will not combine in real life, feeding the decoder
612 * with artificial data can confuse the logic.
613 */
614#define VBI_EVENT_NETWORK 0x0008
615/**
616 * @anchor VBI_EVENT_TRIGGER
617 *
618 * Triggers are sent by broadcasters to start some action on the
619 * user interface of modern TVs. Until libzvbi implements all ;-) of
620 * WebTV and SuperTeletext the information available are program
621 * related (or unrelated) URLs, short messages and Teletext
622 * page links.
623 *
624 * This event is sent when a trigger has fired, ev.trigger
625 * points to a vbi_link structure describing the link in detail.
626 * The structure must be read only.
627 */
628#define VBI_EVENT_TRIGGER 0x0010
629/**
630 * @anchor VBI_EVENT_ASPECT
631 *
632 * The vbi decoder received new information (potentially from
633 * PAL WSS, NTSC XDS or EIA-J CPR-1204) about the program
634 * aspect ratio. ev.ratio is a pointer to a vbi_ratio structure.
635 * The structure must be read only.
636 */
637#define VBI_EVENT_ASPECT 0x0040
638/**
639 * We have new information about the current or next program.
640 * ev.prog_info is a vbi_program_info pointer (due to size), read only.
641 *
642 * Preliminary.
643 *
644 * XXX Info from Teletext not implemented yet.
645 * XXX Change to get_prog_info. network ditto?
646 */
647#define VBI_EVENT_PROG_INFO 0x0080
648/**
649 * Like @a VBI_EVENT_NETWORK, but this event will also be sent
650 * when the decoder cannot determine a network name.
651 *
652 * @since 0.2.20
653 */
654#define VBI_EVENT_NETWORK_ID 0x0100
655/** @} */
656
657/**
658 * @example examples/network.c
659 * Network identification example.
660 */
661
662#include <inttypes.h>
663
664/**
665 * @ingroup Event
666 * @brief Event union.
667 */
668/* XXX network, aspect, prog_info: should only notify about
669 * changes and provide functions to query current value.
670 */
671typedef struct vbi_event {
672 int type;
673 union {
674 struct {
675 int pgno;
676 int subno;
677 uint8_t * raw_header;
678 int pn_offset;
679 unsigned int roll_header : 1;
680 unsigned int header_update : 1;
681 unsigned int clock_update : 1;
682 } ttx_page;
683 struct {
684 int pgno;
685 } caption;
686 vbi_network network;
687 vbi_link * trigger;
688 vbi_aspect_ratio aspect;
689 vbi_program_info * prog_info;
690 } ev;
691} vbi_event;
692
693/**
694 * @addtogroup Event
695 * @{
696 */
697typedef void (* vbi_event_handler)(vbi_event *event, void *user_data);
698
699extern vbi_bool vbi_event_handler_add(vbi_decoder *vbi, int event_mask,
700 vbi_event_handler handler,
701 void *user_data);
702extern void vbi_event_handler_remove(vbi_decoder *vbi,
703 vbi_event_handler handler);
704extern vbi_bool vbi_event_handler_register(vbi_decoder *vbi, int event_mask,
705 vbi_event_handler handler,
706 void *user_data);
707extern void vbi_event_handler_unregister(vbi_decoder *vbi,
708 vbi_event_handler handler,
709 void *user_data);
710/** @} */
711
712/* Private */
713
714extern void vbi_send_event(vbi_decoder *vbi, vbi_event *ev);
715
716#endif /* EVENT_H */
717
718/*
719Local variables:
720c-set-style: K&R
721c-basic-offset: 8
722End:
723*/
724