summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/tex
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2016-03-11 12:12:57 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2016-03-11 12:12:57 +0000
commitb6607d1a70f236fc9f671ce2621978a410e649b1 (patch)
tree57ad797c7a6b132d736a9f15d00eec5e6ebd2a13 /Build/source/texk/web2c/luatexdir/tex
parent7cd1d4e0b78e2897415639c5ac54d796c6cb626e (diff)
web2c/luatexdir: sync with the upstream
git-svn-id: svn://tug.org/texlive/trunk@39996 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/tex')
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/directions.h13
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/directions.w5
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/linebreak.w16
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/maincontrol.w8
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mlist.w9
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/packaging.w159
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texmath.w4
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.h3
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.w33
9 files changed, 203 insertions, 47 deletions
diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.h b/Build/source/texk/web2c/luatexdir/tex/directions.h
index e4cea9014dd..8fe126bdb19 100644
--- a/Build/source/texk/web2c/luatexdir/tex/directions.h
+++ b/Build/source/texk/web2c/luatexdir/tex/directions.h
@@ -39,6 +39,7 @@ extern const char *dir_strings[8];
extern int dir_swap;
+/*
# define RETURN_DIR_VALUES(a) \
if (s==luaS_##a##_ptr) { \
return (dir_##a); \
@@ -48,9 +49,17 @@ extern int dir_swap;
else if (s==luaS_m##a##_ptr) \
return ((dir_##a)-4); \
}
+*/
-# define BOX_DIR_VALUE(a) \
- ((s==luaS_p##a##_ptr) : (dir_##a) ? ((s==luaS_m##a##_ptr) : ((dir_##a)-4) ? luaS_pTLT))
+# define RETURN_DIR_VALUES(a) \
+ if (s==lua_key(a)) { \
+ return (dir_##a); \
+ } else if (!absolute_only) { \
+ if (s==lua_key_plus(a)) \
+ return (dir_##a); \
+ else if (s==lua_key_minus(a)) \
+ return ((dir_##a)-4); \
+ }
# define is_mirrored(a) 0
diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.w b/Build/source/texk/web2c/luatexdir/tex/directions.w
index b010eb4a9cc..7af25187999 100644
--- a/Build/source/texk/web2c/luatexdir/tex/directions.w
+++ b/Build/source/texk/web2c/luatexdir/tex/directions.w
@@ -154,6 +154,8 @@ scaled pack_width(int curdir, int pdir, halfword p, boolean isglyph)
} else {
wd = glyph_depth(p) + glyph_height(p);
}
+/* experimental */
+wd += x_advance(p);
} else { /* hlist, vlist, image, form, rule */
if (textdir_parallel(pdir, curdir))
wd = width(p);
@@ -164,8 +166,7 @@ scaled pack_width(int curdir, int pdir, halfword p, boolean isglyph)
}
@ @c
-scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p,
- boolean isglyph)
+scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p, boolean isglyph)
{
scaled_whd whd = { 0, 0, 0 };
whd.wd = pack_width(curdir, pdir, p, isglyph);
diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.w b/Build/source/texk/web2c/luatexdir/tex/linebreak.w
index b2909606d48..29146424fe4 100644
--- a/Build/source/texk/web2c/luatexdir/tex/linebreak.w
+++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.w
@@ -1286,7 +1286,7 @@ static void ext_try_break(int pi,
}
shortfall += (left_pw(l1) + right_pw(o));
}
- if ((shortfall != 0) && (adjust_spacing == 2)) {
+ if (shortfall != 0) {
margin_kern_stretch = 0;
margin_kern_shrink = 0;
if (protrude_chars > 1) {
@@ -1302,14 +1302,12 @@ static void ext_try_break(int pi,
}
flush_node(cp);
}
- if ((shortfall > 0)
- && ((total_font_stretch + margin_kern_stretch) > 0)) {
+ if ((shortfall > 0) && ((total_font_stretch + margin_kern_stretch) > 0)) {
if ((total_font_stretch + margin_kern_stretch) > shortfall)
shortfall = ((total_font_stretch + margin_kern_stretch) / (max_stretch_ratio / cur_font_step)) / 2;
else
shortfall -= (total_font_stretch + margin_kern_stretch);
- } else if ((shortfall < 0)
- && ((total_font_shrink + margin_kern_shrink) > 0)) {
+ } else if ((shortfall < 0) && ((total_font_shrink + margin_kern_shrink) > 0)) {
if ((total_font_shrink + margin_kern_shrink) > -shortfall)
shortfall = -((total_font_shrink + margin_kern_shrink) / (max_shrink_ratio / cur_font_step)) / 2;
else
@@ -1620,6 +1618,9 @@ void ext_do_line_break(int paragraph_dir,
minimal_demerits[loose_fit] = awful_bad;
minimal_demerits[very_loose_fit] = awful_bad;
+ fewest_demerits = 0;
+ actual_looseness = 0;
+
/* We compute the values of |easy_line| and the other local variables relating
to line length when the |line_break| procedure is initializing itself. */
if (par_shape_ptr == null) {
@@ -1866,8 +1867,9 @@ void ext_do_line_break(int paragraph_dir,
if (prev_p != temp_head && (
is_char_node(prev_p)
|| precedes_break(prev_p)
- || ((type(prev_p) == kern_node) && (subtype(prev_p) != explicit_kern &&
- subtype(prev_p) != italic_kern ))
+ || ( (type(prev_p) == kern_node) && (
+ subtype(prev_p) == font_kern || subtype(prev_p) == accent_kern)
+ )
)) {
ext_try_break(0, unhyphenated_node, line_break_dir, adjust_spacing,
par_shape_ptr, adj_demerits,
diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w
index f36283b58bb..12a4bbab583 100644
--- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w
+++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w
@@ -1518,7 +1518,7 @@ void new_graf(boolean indented)
mode = hmode;
space_factor = 1000;
/* LOCAL: Add local paragraph node */
- tail_append(make_local_par_node());
+ tail_append(make_local_par_node(0));
if (indented) {
p = new_null_box();
box_dir(p) = par_direction;
@@ -1888,7 +1888,7 @@ void build_local_box(void)
eq_define(local_right_box_base, box_ref_cmd, p);
if (abs(mode) == hmode) {
/* LOCAL: Add local paragraph node */
- tail_append(make_local_par_node());
+ tail_append(make_local_par_node(1));
}
eq_word_define(int_base + no_local_whatsits_code, no_local_whatsits + 1);
}
@@ -2851,7 +2851,7 @@ void fixup_directions(void)
}
if (temp_no_whatsits != 0) {
/* LOCAL: Add local paragraph node */
- tail_append(make_local_par_node());
+ tail_append(make_local_par_node(2));
}
}
}
@@ -2961,7 +2961,7 @@ void assign_internal_value(int a, halfword p, int val)
((p == (int_base + local_inter_line_penalty_code)) ||
(p == (int_base + local_broken_penalty_code)))) {
/* LOCAL: Add local paragraph node */
- tail_append(make_local_par_node());
+ tail_append(make_local_par_node(3));
eq_word_define(int_base + no_local_whatsits_code,
no_local_whatsits + 1);
diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.w b/Build/source/texk/web2c/luatexdir/tex/mlist.w
index 1a8e332136d..220e8722386 100644
--- a/Build/source/texk/web2c/luatexdir/tex/mlist.w
+++ b/Build/source/texk/web2c/luatexdir/tex/mlist.w
@@ -1590,9 +1590,12 @@ void run_mlist_to_hlist(halfword p, boolean penalties, int mstyle)
return;
}
alink(p) = null ;
- nodelist_to_lua(L, p); /* arg 1 */
- lua_pushstring(L, math_style_names[mstyle]); /* arg 2 */
- lua_pushboolean(L, penalties); /* arg 3 */
+ nodelist_to_lua(L, p);
+ /*
+ lua_pushstring(L, math_style_names[mstyle]);
+ */
+ lua_push_math_style_name(L,mstyle);
+ lua_pushboolean(L, penalties);
if (lua_pcall(L, 3, 1, 0) != 0) { /* 3 args, 1 result */
char errmsg[256]; /* temp hack ... we will have a formatted error */
snprintf(errmsg, 255, "error: %s\n", lua_tostring(L, -1));
diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.w b/Build/source/texk/web2c/luatexdir/tex/packaging.w
index 7541339dc36..8c692ae7975 100644
--- a/Build/source/texk/web2c/luatexdir/tex/packaging.w
+++ b/Build/source/texk/web2c/luatexdir/tex/packaging.w
@@ -341,6 +341,16 @@ void set_prev_char_p(halfword p)
prev_char_p = p;
}
+/*
+ the kern stretch / shrink code was (or had become) rather weird ... the width field
+ is set, and then used in a second calculation, repeatedly, so why is that ... maybe some
+ some weird left-over ... anyway, the values are so small that in practice they are not
+ significant at all when the backend sees them because a few hundred sp positive or
+ negative are just noise there (so adjustlevel 3 has hardly any consequence for the
+ result but is more efficient)
+*/
+
+
@ @c
scaled char_stretch(halfword p)
{
@@ -350,7 +360,7 @@ scaled char_stretch(halfword p)
int c = character(p);
int ef = get_ef_code(f, c);
if (ef > 0) {
- scaled dw = calc_char_width(f, c, m) - char_width(f, c);
+ scaled dw = calc_char_width(f, c, m) - char_width(f, c) - x_advance(p);
if (dw > 0) {
return round_xn_over_d(dw, ef, 1000);
}
@@ -368,7 +378,7 @@ scaled char_shrink(halfword p)
int c = character(p);
int ef = get_ef_code(f, c);
if (ef > 0) {
- scaled dw = char_width(f, c) - calc_char_width(f, c, -m);
+ scaled dw = char_width(f, c) + x_advance(p) - calc_char_width(f, c, -m);
if (dw > 0) {
return round_xn_over_d(dw, ef, 1000);
}
@@ -378,6 +388,7 @@ scaled char_shrink(halfword p)
}
@ @c
+/*
scaled kern_stretch(halfword p)
{
halfword l, r;
@@ -386,23 +397,69 @@ scaled kern_stretch(halfword p)
if ((prev_char_p == null) || (vlink(prev_char_p) != p) || (vlink(p) == null))
return 0;
l = prev_char_p;
- /* we need a left char */
+ // we need a left char
if (!is_char_node(l))
return 0;
r = vlink(p);
- /* and a right char */
+ // and a right char
if (!is_char_node(r))
return 0;
- /* and a reason to kern */
+ // and a reason to kern
if ((font(l) != font(r)) || (font_max_stretch(font(l)) == 0))
return 0;
m = font_max_stretch(font(l));
- d = get_kern(font(l), character(l), character(r));
+ d = get_kern(font(l), character(l), character(r)); // real kern, so what is width(p) then; the messed up one
d = round_xn_over_d(d, 1000 + m, 1000);
return round_xn_over_d(d - width(p), get_ef_code(font(l), character(l)), 1000);
}
+*/
+
+scaled kern_stretch(halfword p)
+{
+ int m;
+ scaled d, e, x;
+ scaled w = width(p) ;
+ halfword l;
+ halfword r;
+ if (w == 0) {
+ /* why bother about zero kerns */
+ return 0;
+ }
+ l = prev_char_p ;
+ if ((l == null) || (vlink(l) != p)) {
+ /* we only care about kerns following a char*/
+ return 0;
+ }
+ r = vlink(p);
+ if (r == null) {
+ /* we only care about kerns between a char and something else */
+ }
+ if (!(is_char_node(l) && is_char_node(r))) {
+ /* we want two chars (but but don't care about the fonts) */
+ return 0;
+ }
+ /* we use the old logic, kind of, but average the ef as we might depend on proper overlap */
+ m = (font_max_shrink(font(l)) + font_max_shrink(font(r)))/2;
+ if (m == 0) {
+ /* nothing to kern */
+ return 0;
+ }
+ d = round_xn_over_d(w, 1000 + m, 1000);
+ /* we use the old logic, kind of, but average the ef as we might depend on proper overlap */
+ e = (get_ef_code(font(l), character(l)) + get_ef_code(font(r), character(r)))/2 ;
+ if (e == 1000) {
+ x = d - w;
+ } else {
+ x = round_xn_over_d(d - w, e, 1000);
+ }
+ /*
+ printf("STRETCH w=%i s=%i x=%i\n",w,e+m,x);
+ */
+ return x;
+}
@ @c
+/*
scaled kern_shrink(halfword p)
{
halfword l, r;
@@ -411,21 +468,65 @@ scaled kern_shrink(halfword p)
if ((prev_char_p == null) || (vlink(prev_char_p) != p) || (vlink(p) == null))
return 0;
l = prev_char_p;
- /* we need a left char */
+ // we need a left char
if (!is_char_node(l))
return 0;
r = vlink(p);
- /* and a right char */
+ // and a right char
if (!is_char_node(r))
return 0;
- /* and a reason to kern */
+ // and a reason to kern
if ((font(l) != font(r)) || (font_max_shrink(font(l)) == 0))
return 0;
m = font_max_stretch(font(l));
- d = get_kern(font(l), character(l), character(r));
+ d = get_kern(font(l), character(l), character(r)); // real kern, so what is width(p) then; the messed up one
d = round_xn_over_d(d, 1000 - m, 1000);
return round_xn_over_d(width(p) - d, get_ef_code(font(l), character(l)), 1000);
}
+*/
+
+scaled kern_shrink(halfword p)
+{
+ int m;
+ scaled d, e, x;
+ scaled w = width(p) ;
+ halfword l;
+ halfword r;
+ if (w == 0) {
+ /* why bother about zero kerns */
+ return 0;
+ }
+ l = prev_char_p ;
+ if ((l == null) || (vlink(l) != p)) {
+ /* we only care about kerns following a char*/
+ return 0;
+ }
+ r = vlink(p);
+ if (r == null) {
+ /* we only care about kerns between a char and something else */
+ }
+ if (!(is_char_node(l) && is_char_node(r))) {
+ /* we want two chars (but but don't care about the fonts) */
+ return 0;
+ }
+ /* we use the old logic, kind of, but average the ef as we might depend on proper overlap */
+ m = (font_max_shrink(font(l)) + font_max_shrink(font(r)))/2;
+ if (m == 0) {
+ /* nothing to kern */
+ return 0;
+ }
+ d = round_xn_over_d(w, 1000 - m, 1000);
+ e = (get_ef_code(font(l), character(l)) + get_ef_code(font(r), character(r)))/2 ;
+ if (e == 1000) {
+ x = w - d ;
+ } else {
+ x = round_xn_over_d(w - d, e, 1000);
+ }
+ /*
+ printf("SHRINK w=%i s=%i x=%i\n",w,e+m,x);
+ */
+ return x;
+}
@ @c
void do_subst_font(halfword p, int ex_ratio)
@@ -513,6 +614,8 @@ halfword new_margin_kern(scaled w, halfword p, int side)
expansion is being used.
@c
+int font_expand_ratio = 0; /* current expansion ratio, needed for recursive call */
+
halfword hpack(halfword p, scaled w, int m, int pack_direction)
{
halfword r; /* the box node that will be returned */
@@ -530,8 +633,11 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction)
halfword pack_interrupt[8];
scaled font_stretch = 0;
scaled font_shrink = 0;
- int font_expand_ratio = 0; /* current expansion ratio */
- scaled k = 0;
+ int adjust_spacing = int_par(adjust_spacing_code);
+
+/*
+ int font_expand_ratio = 0;
+*/
last_badness = 0;
r = new_node(hlist_node, min_quarterword); /* the box node that will be returned */
if (pack_direction == -1) {
@@ -555,6 +661,9 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction)
if (m == cal_expand_ratio) {
prev_char_p = null; /* why not always */
}
+ if (adjust_spacing > 2) {
+ adjust_spacing = 0;
+ }
total_stretch[normal] = 0;
total_shrink[normal] = 0;
total_stretch[sfi] = 0;
@@ -664,20 +773,27 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction)
}
break;
case kern_node:
- if (subtype(p) == normal) {
+ x += width(p);
+ if (subtype(p) == font_kern && adjust_spacing) {
+ /* so only when 1 or 2 */
if (m == cal_expand_ratio) {
font_stretch = font_stretch + kern_stretch(p);
font_shrink = font_shrink + kern_shrink(p);
} else if (m == subst_ex_font) {
- if (font_expand_ratio > 0)
+ /* this is the finalizer */
+ int k = 0;
+ if (font_expand_ratio > 0) {
k = kern_stretch(p);
- else if (font_expand_ratio < 0)
+ } else if (font_expand_ratio < 0) {
k = kern_shrink(p);
- if (k != 0)
- width(p) = get_kern(font(prev_char_p), character(prev_char_p), character(vlink(p)));
+ }
+ ex_kern(p) = k;
+ x += k;
+ /*
+ if (x!=0) printf("SET %i %i %i\n",font_expand_ratio,k,x);
+ */
}
}
- x += width(p);
break;
case disc_node:
if (m == subst_ex_font)
@@ -985,10 +1101,13 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction)
q = list_ptr(r);
list_ptr(r) = null;
flush_node(r);
+ /* this nested call uses the more or less global font_expand_ratio */
r = hpack(q, w, subst_ex_font, hpack_dir);
}
while (dir_ptr1 != null)
pop_dir_node(dir_ptr1);
+ /* here we reset the font_expan_ratio */
+ font_expand_ratio = 0;
return r;
}
@@ -1119,9 +1238,11 @@ scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult,
}
break;
case margin_kern_node:
- case kern_node:
siz.wd += width(p);
break;
+ case kern_node:
+ siz.wd += width(p) + ex_kern(p);
+ break;
case disc_node:
xx = natural_sizes(no_break(p), null, g_mult, g_sign, g_order, hpack_dir);
siz.wd += xx.wd;
diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.w b/Build/source/texk/web2c/luatexdir/tex/texmath.w
index 81cfd9cf733..f501d403597 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texmath.w
+++ b/Build/source/texk/web2c/luatexdir/tex/texmath.w
@@ -2138,8 +2138,8 @@ static void resume_after_display(void)
push_nest();
mode = hmode;
space_factor = 1000;
- tail_append(make_local_par_node()); /* this needs to be intercepted in
- the display math start ! */
+ tail_append(make_local_par_node(4)); /* this needs to be intercepted in
+ the display math start ! */
get_x_token();
if (cur_cmd != spacer_cmd)
back_input();
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
index aad7bfa026d..cbf983d9736 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h
+++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
@@ -252,6 +252,7 @@ typedef enum {
# define x_displace(a) vinfo((a)+4)
# define y_displace(a) vlink((a)+4)
# define ex_glyph(a) vinfo((a)+5) /* expansion factor (hz) */
+# define x_advance(a) vlink((a)+5)
# define is_char_node(a) (a!=null && type(a)==glyph_node)
@@ -944,7 +945,7 @@ extern int lua_properties_use_metatable ;
#define local_left_box equiv(local_left_box_base)
#define local_right_box equiv(local_right_box_base)
-extern halfword make_local_par_node(void);
+extern halfword make_local_par_node(int mode);
#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.w b/Build/source/texk/web2c/luatexdir/tex/texnodes.w
index de718139923..698fb76e82d 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texnodes.w
+++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.w
@@ -473,8 +473,7 @@ important, don't keep resolving the registry index.
if (lua_properties_enabled) { \
lua_properties_level = lua_properties_level + 1 ; \
if (lua_properties_level == 1) { \
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, luaS_index(node_properties)); \
- lua_gettable(Luas, LUA_REGISTRYINDEX); \
+ lua_get_metatablelua_l(Luas,node_properties); \
} \
} \
} while(0)
@@ -497,8 +496,7 @@ important, don't keep resolving the registry index.
#define lua_properties_reset(target) do { \
if (lua_properties_enabled) { \
if (lua_properties_level == 0) { \
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, luaS_index(node_properties)); \
- lua_gettable(Luas, LUA_REGISTRYINDEX); \
+ lua_get_metatablelua_l(Luas,node_properties); \
lua_pushnil(Luas); \
lua_rawseti(Luas,-2,target); \
lua_pop(Luas,1); \
@@ -549,8 +547,7 @@ important, don't keep resolving the registry index.
#define lua_properties_copy(target,source) do { \
if (lua_properties_enabled) { \
if (lua_properties_level == 0) { \
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, luaS_index(node_properties)); \
- lua_gettable(Luas, LUA_REGISTRYINDEX); \
+ lua_get_metatablelua_l(Luas,node_properties); \
lua_rawgeti(Luas,-1,source); \
if (lua_type(Luas,-1)==LUA_TTABLE) { \
if (lua_properties_use_metatable) { \
@@ -3708,8 +3705,9 @@ the \.{WEB} macro definitions above, so that format changes will leave
@c
-halfword make_local_par_node(void)
+halfword make_local_par_node(int mode)
{
+ int callback_id;
halfword q;
halfword p = new_node(local_par_node,0);
local_pen_inter(p) = local_inter_line_penalty;
@@ -3725,5 +3723,26 @@ halfword make_local_par_node(void)
local_box_right_width(p) = width(local_right_box);
}
local_par_dir(p) = par_direction;
+ /* callback with node passed */
+ callback_id = callback_defined(insert_local_par_callback);
+ if (callback_id > 0) {
+ int sfix = lua_gettop(Luas);
+ if (!get_callback(Luas, callback_id)) {
+ lua_settop(Luas, sfix);
+ return p;
+ }
+ nodelist_to_lua(Luas, p);
+ lua_push_local_par_mode(Luas,mode)
+ if (lua_pcall(Luas, 2, 0, 0) != 0) { /* 2 arg, 0 result */
+ char errmsg[256]; /* temp hack ... we will have a formatted error */
+ snprintf(errmsg, 255, "error: %s\n", lua_tostring(Luas, -1));
+ errmsg[255]='\0';
+ lua_settop(Luas, sfix);
+ normal_error("insert_local_par",errmsg); /* to be done */
+ return p;
+ }
+ lua_settop(Luas, sfix);
+ }
+ /* done */
return p;
}