Commit ab6e30d01d70d7cfc77b96de0d864d32b0000483

Authored by totoro
1 parent 4412b0a2

Add the support of json string formating extension

Add new HTTP_ANSWER which is json. This is useful when there is a need to return json only i.e. in ajax call
extensions/json.anubis 0 → 100644
  1 +/*
  2 + * Created by PyramIDE.
  3 + * User: フランスのトトロ
  4 + * Date: 12/12/2015
  5 + * Time: 21:48
  6 + * © Calexium
  7 + */
  8 +
  9 +read tools/basis.anubis
  10 +
  11 +public define String
  12 + lib_error_to_string
  13 + (
  14 + LibraryError err
  15 + )=
  16 + if err is
  17 + {
  18 + cant_load_library then "Can't load library.",
  19 + symbol_not_found then "Symbol not found.",
  20 + external_call_failed then "External call failed.",
  21 + unknown_error then "Unknown error."
  22 + }.
  23 +
  24 +public define String
  25 + to_JS_String
  26 + (
  27 + Library json_lib,
  28 + String unescaped_string
  29 + )=
  30 + if unescaped_string = "" then
  31 + "''"
  32 + else
  33 + if extension_library_call(json_lib, "to_JS_String", serialize(unescaped_string), length(unescaped_string)+30) is
  34 + {
  35 + error(err) then
  36 + println("Can't call to_JS_String");
  37 + println(" --> " + lib_error_to_string(err));
  38 + "''",
  39 + ok(ba) then to_string(ba)
  40 + }.
  41 +
  42 +public define String
  43 + to_JSON_String
  44 + (
  45 + Library json_lib,
  46 + String unescaped_string
  47 + )=
  48 + if unescaped_string = "" then
  49 + "\"\""
  50 + else
  51 + if extension_library_call(json_lib, "to_JSON_String", serialize(unescaped_string), length(unescaped_string)+30) is
  52 + {
  53 + error(err) then
  54 + println("Can't call to_JSON_String");
  55 + println(" --> " + lib_error_to_string(err));
  56 + "\"\"",
  57 + ok(ba) then to_string(ba)
  58 + }.
  59 +
web/CXM_json.anubis
@@ -11,6 +11,8 @@ read tools/basis.anubis @@ -11,6 +11,8 @@ read tools/basis.anubis
11 read tools/printable_tree.anubis 11 read tools/printable_tree.anubis
12 transmit web/mime.anubis 12 transmit web/mime.anubis
13 13
  14 +transmit calexium_lib/extensions/json.anubis
  15 +
14 public type JsonMember:... 16 public type JsonMember:...
15 17
16 18
@@ -28,6 +30,18 @@ public type JsonMember: @@ -28,6 +30,18 @@ public type JsonMember:
28 json_member(String name, 30 json_member(String name,
29 JsonValue value). 31 JsonValue value).
30 32
  33 +public define Printable_tree
  34 + _format_json
  35 + (
  36 + JsonValue json
  37 + ).
  38 +
  39 +public define Printable_tree
  40 + _format_json
  41 + (
  42 + Library json_lib,
  43 + JsonValue json
  44 + ).
31 //------------------------------- 45 //-------------------------------
32 // helpers 46 // helpers
33 47
@@ -99,7 +113,7 @@ define List(Word8) @@ -99,7 +113,7 @@ define List(Word8)
99 ) = 113 ) =
100 if original is 114 if original is
101 { 115 {
102 - [] then new_string, 116 + [] then ['\"' . new_string], //add trailing double quotes
103 [h . t] then 117 [h . t] then
104 if (h >=+ 32 & h +=< 33) | (h >=+ 35 & h +=< 91) | h >=+ 93 then // Allowed characters for JSON see RFC4627 + " ' " Why ' ??? 118 if (h >=+ 32 & h +=< 33) | (h >=+ 35 & h +=< 91) | h >=+ 93 then // Allowed characters for JSON see RFC4627 + " ' " Why ' ???
105 _format_json_esc(t, [h . new_string]) 119 _format_json_esc(t, [h . new_string])
@@ -115,7 +129,7 @@ public define String @@ -115,7 +129,7 @@ public define String
115 ( 129 (
116 String original, 130 String original,
117 ) = 131 ) =
118 - implode(reverse(_format_json_esc(explode(original), [],))). 132 + implode(reverse(_format_json_esc(explode(original), ['\"'],))).
119 133
120 134
121 public define Printable_tree 135 public define Printable_tree
@@ -136,9 +150,18 @@ public define Printable_tree @@ -136,9 +150,18 @@ public define Printable_tree
136 JsonMember member 150 JsonMember member
137 ) = 151 ) =
138 if member is json_member(name, value) then 152 if member is json_member(name, value) then
139 - [ "\"", name, "\":" . format_json(value) ]. 153 + [ "\"", name, "\":" . _format_json(value) ].
140 154
141 public define Printable_tree 155 public define Printable_tree
  156 + format_json_member
  157 + (
  158 + Library json_lib,
  159 + JsonMember member
  160 + ) =
  161 + if member is json_member(name, value) then
  162 + [ "\"", name, "\":" . _format_json(json_lib, value) ].
  163 +
  164 +public define Printable_tree
142 json_member_to_js 165 json_member_to_js
143 ( 166 (
144 JsonMember member 167 JsonMember member
@@ -149,13 +172,25 @@ public define Printable_tree @@ -149,13 +172,25 @@ public define Printable_tree
149 define Printable_tree 172 define Printable_tree
150 format_json_object 173 format_json_object
151 ( 174 (
152 - List(JsonMember) members 175 + List(JsonMember) members
153 ) = 176 ) =
154 if members is 177 if members is
155 { 178 {
156 [] then [], 179 [] then [],
157 [h . t] then [ format_json_member(h), (if t is [] then "" else ",") . format_json_object(t) ] 180 [h . t] then [ format_json_member(h), (if t is [] then "" else ",") . format_json_object(t) ]
158 }. 181 }.
  182 +
  183 +define Printable_tree
  184 + format_json_object
  185 + (
  186 + Library json_lib,
  187 + List(JsonMember) members
  188 + ) =
  189 + if members is
  190 + {
  191 + [] then [],
  192 + [h . t] then [ format_json_member(json_lib, h), (if t is [] then "" else ",") . format_json_object(json_lib, t) ]
  193 + }.
159 194
160 define Printable_tree 195 define Printable_tree
161 json_object_to_js 196 json_object_to_js
@@ -171,70 +206,101 @@ define Printable_tree @@ -171,70 +206,101 @@ define Printable_tree
171 define Printable_tree 206 define Printable_tree
172 format_json_array 207 format_json_array
173 ( 208 (
  209 + Library json_lib,
174 List(JsonValue) values 210 List(JsonValue) values
175 ) = 211 ) =
176 if values is 212 if values is
177 { 213 {
178 - [] then [],  
179 - [h . t] then [ format_json(h), (if t is [] then "" else ",") . format_json_array(t) ] 214 + [] then [],
  215 + [h . t] then [ _format_json(json_lib, h), (if t is [] then "" else ",") . format_json_array(json_lib, t) ]
180 }. 216 }.
181 217
182 define Printable_tree 218 define Printable_tree
183 - json_array_to_js 219 + format_json_array
184 ( 220 (
185 List(JsonValue) values 221 List(JsonValue) values
186 ) = 222 ) =
187 if values is 223 if values is
188 { 224 {
189 [] then [], 225 [] then [],
190 - [h . t] then [ to_javascript(h), (if t is [] then "" else ",") . format_json_array(t) ] 226 + [h . t] then [ _format_json(h), (if t is [] then "" else ",") . format_json_array(t) ]
191 }. 227 }.
192 228
193 public define Printable_tree 229 public define Printable_tree
194 - format_json 230 + _format_json
195 ( 231 (
  232 + Library json_lib,
196 JsonValue json 233 JsonValue json
197 ) = 234 ) =
198 if json is 235 if json is
199 { 236 {
200 - json_object(members) then [ "{", format_json_object(members), "}" . [] ],  
201 - json_array(values) then [ "[", format_json_array(values), "]" . [] ], 237 + json_object(members) then [ "{", format_json_object(json_lib, members), "}" . [] ],
  238 + json_array(values) then [ "[", format_json_array(json_lib, values), "]" . [] ],
202 json_int(i) then int_pt(i, []), 239 json_int(i) then int_pt(i, []),
203 json_float(f, p) then str_pt(float_to_string(f, p), []), 240 json_float(f, p) then str_pt(float_to_string(f, p), []),
204 - json_string(s) then str_pt("\"" + format_json_esc(s) + "\"", []), 241 + json_string(s) then if s ="" then str_pt("\"\"", []) else str_pt(to_JSON_String(json_lib, s), []),
205 json_bool(b) then str_pt(if b then "true" else "false", []), 242 json_bool(b) then str_pt(if b then "true" else "false", []),
206 json_null then str_pt("null", []) 243 json_null then str_pt("null", [])
207 }. 244 }.
208 245
209 public define Printable_tree 246 public define Printable_tree
210 - to_javascript 247 + _format_json
211 ( 248 (
212 JsonValue json 249 JsonValue json
213 ) = 250 ) =
214 if json is 251 if json is
215 { 252 {
216 - json_object(members) then [ "{", json_object_to_js(members), "}" . [] ],  
217 - json_array(values) then [ "[", json_array_to_js(values), "]" . [] ], 253 + json_object(members) then [ "{", format_json_object(members), "}" . [] ],
  254 + json_array(values) then [ "[", format_json_array(values), "]" . [] ],
218 json_int(i) then int_pt(i, []), 255 json_int(i) then int_pt(i, []),
219 json_float(f, p) then str_pt(float_to_string(f, p), []), 256 json_float(f, p) then str_pt(float_to_string(f, p), []),
220 - json_string(s) then str_pt("\"" + format_json_esc(s) + "\"", []), 257 + json_string(s) then str_pt(format_json_esc(s), []),
221 json_bool(b) then str_pt(if b then "true" else "false", []), 258 json_bool(b) then str_pt(if b then "true" else "false", []),
222 json_null then str_pt("null", []) 259 json_null then str_pt("null", [])
223 }. 260 }.
224 -  
225 -public define String 261 +
  262 +public define Printable_tree
226 format_json 263 format_json
227 ( 264 (
228 - JsonValue json 265 + JsonValue json
229 ) = 266 ) =
230 - to_String(format_json(json)). 267 + //try to use adl version of json escape string
  268 + if load_library("json") is
  269 + {
  270 + error(err) then
  271 + println("load lib error:");
  272 + println("--> can't load extension lib. Hence use anubis version");
  273 + _format_json(json)
  274 + ok(json_lib) then
  275 + with start = unow,
  276 + result = _format_json(json_lib, json),
  277 + println(show_duration_string("format_json with extension ",start));
  278 + result
  279 + }.
  280 +
  281 +public define String
  282 + to_JSON_String
  283 + (
  284 + String str
  285 + ) =
  286 + //try to use adl version of json escape string
  287 + if load_library("json") is
  288 + {
  289 + error(err) then
  290 + println("load lib error:");
  291 + println("--> can't load extension lib. Hence use anubis version");
  292 + format_json_esc(str)
  293 + ok(json_lib) then
  294 + to_JSON_String(json_lib, str)
  295 + }.
231 296
232 public define String 297 public define String
233 - to_javascript 298 + format_json
234 ( 299 (
235 - JsonValue json 300 + JsonValue json
236 ) = 301 ) =
237 - to_String(to_javascript(json)). 302 + to_String(format_json(json)).
  303 +
238 304
239 public define WriteFileResult 305 public define WriteFileResult
240 write_to_file 306 write_to_file
web/CXM_making_a_web_site.anubis
@@ -57,7 +57,7 @@ read CXM_common.anubis @@ -57,7 +57,7 @@ read CXM_common.anubis
57 read CXM_multihost_http_server.anubis 57 read CXM_multihost_http_server.anubis
58 read web/mime.anubis 58 read web/mime.anubis
59 read CXM_cookies.anubis 59 read CXM_cookies.anubis
60 - 60 +read CXM_json.anubis
61 61
62 * (1) Structure of a web site. 62 * (1) Structure of a web site.
63 63
@@ -1675,6 +1675,8 @@ public type HTTP_Answer: @@ -1675,6 +1675,8 @@ public type HTTP_Answer:
1675 custom_tree (HTTP_Status /*http_status*/, 1675 custom_tree (HTTP_Status /*http_status*/,
1676 MIME /*mime_type*/, 1676 MIME /*mime_type*/,
1677 Printable_tree /*content*/), 1677 Printable_tree /*content*/),
  1678 + json (HTTP_Status, /*http_status*/
  1679 + JsonValue), /*json value*/
1678 http_raw (Printable_tree), 1680 http_raw (Printable_tree),
1679 html_content (HTTP_Status /*http_status*/, 1681 html_content (HTTP_Status /*http_status*/,
1680 HTML_Off_Form), 1682 HTML_Off_Form),
@@ -4915,7 +4917,19 @@ public define Printable_tree @@ -4915,7 +4917,19 @@ public define Printable_tree
4915 crlf . 4917 crlf .
4916 content 4918 content
4917 ], 4919 ],
4918 - 4920 + json(HTTP_Status status, JsonValue json_content) then
  4921 + with start = unow,
  4922 + with content = (Printable_tree)format_json(json_content),
  4923 + println(show_duration_string("HTTP json format json object ", start));
  4924 + if format(status) is (status_string, status_headers) then
  4925 + [ "HTTP/1.1 " + status_string, crlf,
  4926 + format_headers(standard_headers),
  4927 + format_headers(standard_headers_for(to_String(mime_json), length(content), success(charset))),
  4928 + format_headers(status_headers),
  4929 + format_headers(additional_headers),
  4930 + crlf .
  4931 + content
  4932 + ],
4919 http_raw(Printable_tree content) then content, 4933 http_raw(Printable_tree content) then content,
4920 4934
4921 html_content(HTTP_Status status, HTML_Off_Form content_HTML) then 4935 html_content(HTTP_Status status, HTML_Off_Form content_HTML) then
web/jQuery/CXM_jquery_animate.anubis
@@ -381,7 +381,7 @@ public define List(HTML_Head_Tag) @@ -381,7 +381,7 @@ public define List(HTML_Head_Tag)
381 js_anim_function_name, 381 js_anim_function_name,
382 [ 382 [
383 format_jquery_selector(jq_selector), 383 format_jquery_selector(jq_selector),
384 - to_javascript( 384 + format_json(
385 json_array( 385 json_array(
386 generate_js( 386 generate_js(
387 format_animations([ ], anims), 387 format_animations([ ], anims),
web/jQuery/CXM_jquery_button.anubis
@@ -11,6 +11,7 @@ transmit calexium_lib/web/CXM_jquery.anubis @@ -11,6 +11,7 @@ transmit calexium_lib/web/CXM_jquery.anubis
11 transmit calexium_lib/web/jQuery/CXM_jquery_icons.anubis 11 transmit calexium_lib/web/jQuery/CXM_jquery_icons.anubis
12 transmit calexium_lib/web/widgets/button.anubis 12 transmit calexium_lib/web/widgets/button.anubis
13 transmit calexium_lib/web/js_tools.anubis 13 transmit calexium_lib/web/js_tools.anubis
  14 +transmit calexium_lib/web/CXM_json.anubis
14 transmit tools/basis.anubis 15 transmit tools/basis.anubis
15 transmit system/string.anubis 16 transmit system/string.anubis
16 transmit tools/random.anubis 17 transmit tools/random.anubis
@@ -272,15 +273,15 @@ public define HTML_Partial_Content @@ -272,15 +273,15 @@ public define HTML_Partial_Content
272 )= 273 )=
273 with uid = generate_random_string(10), 274 with uid = generate_random_string(10),
274 275
275 - js_confirm_dialog_data_obj = "CalexiumToolBox.data.confirm_dialog[" + to_js_string(uid) + "]", 276 + js_confirm_dialog_data_obj = "CalexiumToolBox.data.confirm_dialog['" + uid + "']",
276 js_data = js_confirm_dialog_data_obj + " = { 277 js_data = js_confirm_dialog_data_obj + " = {
277 - title: " + to_js_string(dlg_title) + ",  
278 - text: " + to_js_string(dlg_text) + ",  
279 - ok : " + to_js_string(dlg_ok) + ",  
280 - cancel: " + to_js_string(dlg_cancel) + "};", 278 + title: " + to_JS_String(dlg_title) + ",
  279 + text: " + to_JS_String(dlg_text) + ",
  280 + ok : " + to_JS_String(dlg_ok) + ",
  281 + cancel: " + to_JS_String(dlg_cancel) + "};",
281 282
282 button_name = uid, 283 button_name = uid,
283 - actioner = jQuery_actioner(same, jqscript, "CalexiumToolBox.make_confirm_dialog(this, " /*+ to_js_string("/?a=" + url + format_extra_operands(extra_ops))+*/ + to_js_string(jquery_button_get_onclick_action(actioner)) + ");"), 284 + actioner = jQuery_actioner(same, jqscript, "CalexiumToolBox.make_confirm_dialog(this, " /*+ to_js_string("/?a=" + url + format_extra_operands(extra_ops))+*/ + to_JS_String(jquery_button_get_onclick_action(actioner)) + ");"),
284 285
285 partial_content([js(js_file("js/cxm/cxm.js")), js_inline(jquery_ready(js_data))],sequence([ 286 partial_content([js(js_file("js/cxm/cxm.js")), js_inline(jquery_ready(js_data))],sequence([
286 partial(jquery_button(jQuery_button(button, uid, button_name, button_label, actioner, jq_icon_none, jq_icon_none))) 287 partial(jquery_button(jQuery_button(button, uid, button_name, button_label, actioner, jq_icon_none, jq_icon_none)))
@@ -301,15 +302,15 @@ public define HTML_Partial_Content @@ -301,15 +302,15 @@ public define HTML_Partial_Content
301 since button is jquery_img_button(img_url, button_label, button_name, actioner, orientation), 302 since button is jquery_img_button(img_url, button_label, button_name, actioner, orientation),
302 with uid = generate_random_string(10), 303 with uid = generate_random_string(10),
303 304
304 - js_confirm_dialog_data_obj = "CalexiumToolBox.data.confirm_dialog[" + to_js_string(uid) + "]", 305 + js_confirm_dialog_data_obj = "CalexiumToolBox.data.confirm_dialog['" + uid + "']",
305 js_data = js_confirm_dialog_data_obj + " = { 306 js_data = js_confirm_dialog_data_obj + " = {
306 - title: " + to_js_string(dlg_title) + ",  
307 - text: " + to_js_string(dlg_text) + ",  
308 - ok : " + to_js_string(dlg_ok) + ",  
309 - cancel: " + to_js_string(dlg_cancel) + "};", 307 + title: " + to_JS_String(dlg_title) + ",
  308 + text: " + to_JS_String(dlg_text) + ",
  309 + ok : " + to_JS_String(dlg_ok) + ",
  310 + cancel: " + to_JS_String(dlg_cancel) + "};",
310 311
311 button_name = uid, 312 button_name = uid,
312 - actioner = jQuery_actioner(same, jqscript, "CalexiumToolBox.make_confirm_dialog(this, " + to_js_string(jquery_button_get_onclick_action(actioner)) +");"), 313 + actioner = jQuery_actioner(same, jqscript, "CalexiumToolBox.make_confirm_dialog(this, " + to_JS_String(jquery_button_get_onclick_action(actioner)) +");"),
313 314
314 partial_content([js(js_file("js/cxm/cxm.js")), js_inline(jquery_ready(js_data))],sequence([ 315 partial_content([js(js_file("js/cxm/cxm.js")), js_inline(jquery_ready(js_data))],sequence([
315 partial(jquery_button(jquery_img_button(img_url, button_label, button_name, actioner, orientation))) 316 partial(jquery_button(jquery_img_button(img_url, button_label, button_name, actioner, orientation)))
web/js_tools.anubis
@@ -7,9 +7,11 @@ @@ -7,9 +7,11 @@
7 */ 7 */
8 8
9 read tools/basis.anubis 9 read tools/basis.anubis
  10 +read calexium_lib/web/CXM_json.anubis
  11 +transmit calexium_lib/extensions/json.anubis
10 12
11 define List(Word8) 13 define List(Word8)
12 - make_js_string 14 + make_JS_String
13 ( 15 (
14 List(Word8) current, 16 List(Word8) current,
15 List(Word8) so_far 17 List(Word8) so_far
@@ -19,7 +21,7 @@ define List(Word8) @@ -19,7 +21,7 @@ define List(Word8)
19 { 21 {
20 [ ] then reverse(so_far), 22 [ ] then reverse(so_far),
21 [h . t] then 23 [h . t] then
22 - make_js_string(t, 24 + make_JS_String(t,
23 if h = '\'' then [ h, '\\' . so_far] //single quote 25 if h = '\'' then [ h, '\\' . so_far] //single quote
24 else if h = '\"' then [ h, '\\' . so_far] 26 else if h = '\"' then [ h, '\\' . so_far]
25 else if h = '\r' then ['r', '\\' . so_far] //CR 27 else if h = '\r' then ['r', '\\' . so_far] //CR
@@ -35,20 +37,28 @@ define List(Word8) @@ -35,20 +37,28 @@ define List(Word8)
35 * Convert a string into certified javascript string (I hope) 37 * Convert a string into certified javascript string (I hope)
36 */ 38 */
37 public define String 39 public define String
38 - make_js_string 40 + make_JS_String
39 ( 41 (
40 String str 42 String str
41 ) 43 )
42 = 44 =
43 - implode(make_js_string(explode(str), [])). 45 + implode(make_JS_String(explode(str), [])).
  46 +
44 47
45 public define String 48 public define String
46 - to_js_string 49 + to_JS_String
47 ( 50 (
48 String str 51 String str
49 ) 52 )
50 = 53 =
51 - "'" + make_js_string(str) + "'". 54 + //try to use adl version of json escape string
  55 + if load_library("json") is
  56 + {
  57 + error(err) then
  58 + "'" + make_JS_String(str) + "'"
  59 + ok(json_lib) then
  60 + to_JS_String(json_lib, str)
  61 + }.
52 62
53 public define String 63 public define String
54 format_js_function_call 64 format_js_function_call
web/widgets/button.anubis
@@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
8 8
9 read calexium_lib/web/CXM_making_a_web_site.anubis 9 read calexium_lib/web/CXM_making_a_web_site.anubis
10 read calexium_lib/web/CXM_jquery.anubis 10 read calexium_lib/web/CXM_jquery.anubis
  11 +read calexium_lib/web/CXM_json.anubis
11 read calexium_lib/web/js_tools.anubis 12 read calexium_lib/web/js_tools.anubis
12 transmit calexium_lib/web/widgets/icons_set.anubis 13 transmit calexium_lib/web/widgets/icons_set.anubis
13 read tools/basis.anubis 14 read tools/basis.anubis
@@ -88,11 +89,11 @@ define inline String @@ -88,11 +89,11 @@ define inline String
88 String dlg_ok, 89 String dlg_ok,
89 String dlg_cancel 90 String dlg_cancel
90 ) = 91 ) =
91 - "CalexiumToolBox.data.confirm_dialog[" + to_js_string(uid) + "] = " +  
92 - "{ title: " + to_js_string(dlg_title) +  
93 - ", text: " + to_js_string(dlg_text) +  
94 - ", ok : " + to_js_string(dlg_ok) +  
95 - ", cancel: " + to_js_string(dlg_cancel) + 92 + "CalexiumToolBox.data.confirm_dialog['" +(uid) + "'] = " +
  93 + "{ title: " + to_JS_String(dlg_title) +
  94 + ", text: " + to_JS_String(dlg_text) +
  95 + ", ok : " + to_JS_String(dlg_ok) +
  96 + ", cancel: " + to_JS_String(dlg_cancel) +
96 "};". 97 "};".
97 98
98 define List(CoreAttrs) 99 define List(CoreAttrs)
@@ -102,7 +103,7 @@ define List(CoreAttrs) @@ -102,7 +103,7 @@ define List(CoreAttrs)
102 String uid, 103 String uid,
103 JQuery_Actioner actioner 104 JQuery_Actioner actioner
104 ) = 105 ) =
105 - core_attrs + [id(uid), style("cursor: pointer"), event(onclick, "CalexiumToolBox.make_confirm_dialog(this, "/* + to_js_string("/?a=" + url + format_extra_operands(extra_ops))+*/+ to_js_string(jquery_button_get_onclick_action(actioner)) +");")]. 106 + core_attrs + [id(uid), style("cursor: pointer"), event(onclick, "CalexiumToolBox.make_confirm_dialog(this, "/* + to_js_string("/?a=" + url + format_extra_operands(extra_ops))+*/+ to_JS_String(jquery_button_get_onclick_action(actioner)) +");")].
106 107
107 public define HTML_Partial_Content 108 public define HTML_Partial_Content
108 img_button_confirm 109 img_button_confirm