Index: trunk/WikiWord/WikiWordWeb/src/main/www/wikipics/response.atom.php |
— | — | @@ -1,334 +1,54 @@ |
2 | 2 | <?php |
3 | 3 | if (!defined("WIKIPICS")) die("not a valid entry point"); |
4 | 4 | |
5 | | -function printConceptList($langs, $concepts, $class, $limit = false) { |
6 | | - if (!$concepts) return false; |
7 | | - |
8 | | - if (!$limit || $limit > count($concepts)) $limit = count($concepts); |
9 | | - |
10 | | - $i = 0; |
11 | | - ?> |
12 | | - <ul class="<?php print $class; ?>"> |
13 | | - <?php |
14 | | - foreach ($concepts as $c) { |
15 | | - $link = getConceptDetailsLink($langs, $c); |
16 | | - if (!$link) continue; |
17 | | - |
18 | | - ?><li><?php |
19 | | - print $link; |
20 | | - |
21 | | - $i += 1; |
22 | | - if ($i >= $limit) break; |
23 | | - ?></li><?php |
24 | | - } |
25 | | - ?> |
26 | | - </ul> |
27 | | - <?php |
28 | | - |
29 | | - return $i < count($concepts); |
| 5 | +function printConceptEntry( $langs, $concept ) { |
| 6 | + global $utils, $wwDbDate; |
| 7 | + |
| 8 | + extract( $concept ); |
| 9 | + |
| 10 | + $name = $utils->pickLocal($concept['name'], $langs); |
| 11 | + $name = str_replace("_", " ", $name); |
| 12 | + |
| 13 | + if (empty($definition)) $definition = false; |
| 14 | + else if (is_array($definition)) { |
| 15 | + $definition = $utils->pickLocal($definition, $langs); |
| 16 | + $defLang = $utils->pickLanguage($definition, $langs); |
| 17 | + } |
| 18 | + |
| 19 | + $detailsURL = getConceptDetailsURL($langs, $concept); |
| 20 | + $thesaurusURL = false; |
| 21 | + ?> |
| 22 | + <entry> |
| 23 | + <id>sha1:<?php print sha1("$id/$wwDbDate/brief"); ?></id> |
| 24 | + <title><?php print htmlspecialchars($name); ?></title> |
| 25 | + <updated><?php print htmlspecialchars($wwDbDate); ?></updated> |
| 26 | + <link rel="alternate" type="application/atom+xml" href="<?php print htmlspecialchars($detailsURL); ?>"/> |
| 27 | + <?php if($detailsURL) { ?> <link rel="related" type="application/rdf+xml" href="<?php print htmlspecialchars($thesaurusURL); ?>"/> <?php } ?> |
| 28 | + <?php if($thesaurusURL) { ?> <link rel="related" type="text/html" lang="<?php print htmlspecialchars($pageLang); ?>" href="<?php print htmlspecialchars($pageURL); ?>"/> <?php } ?> |
| 29 | + <summary type="text" lang="<?php print htmlspecialchars($defLang); ?>"> |
| 30 | + <?php print htmlspecialchars($definition); ?> |
| 31 | + </summary> |
| 32 | + <content type="xhtml" xmlns="http://www.w3.org/1999/xhtml"> |
| 33 | + <table class="results"> |
| 34 | + <?php printConcept($concept, $langs, true); /*HTML!*/ ?> |
| 35 | + </table> |
| 36 | + </content> |
| 37 | + <?php |
| 38 | + //use http://a9.com/-/spec/opensearch/1.1/subset and http://a9.com/-/spec/opensearch/1.1/superset |
| 39 | + //use both atom:link and opensearch:link! |
| 40 | + listRelatedConcepts($concept); |
| 41 | + listImageEnclosures($concept); |
| 42 | + ?> |
| 43 | + </entry> |
| 44 | + <?php |
30 | 45 | } |
31 | 46 | |
32 | | -function printConceptImageList($concept, $terse = false, $columns = 5, $limit = false ) { |
33 | | - global $utils, $wwThumbSize; |
34 | | - |
35 | | - if (!$concept) return false; |
36 | | - |
37 | | - if (is_array($concept) && !isset($concept['id'])) $images = $concept; #XXX: HACK |
38 | | - else $images = getImagesAbout($concept, $max ? $max +1 : false); |
39 | | - |
40 | | - if (!$images) return; |
41 | | - |
42 | | - $class = $terse ? "terseImageTable" : ""; |
43 | | - |
44 | | - $imgList = array_values($images); |
45 | | - |
46 | | - $cw = $wwThumbSize + 32; //FIXME: magic number, use config! |
47 | | - |
48 | | - ?> |
49 | | - <table class="imageTable <?php print $class; ?>" summary="images" width="<?php print $columns*$cw; ?>"> |
50 | | - <colgroup span="<?php print $columns; ?>" width="<?php print $cw; ?>"> |
51 | | - </colgroup> |
52 | | - |
53 | | - <?php |
54 | | - $i = 0; |
55 | | - $c = count($images); |
56 | | - if (!$limit || $limit > $c) $limit = $c; |
57 | | - |
58 | | - while ($i < $limit) { |
59 | | - $i = printConceptImageRow($imgList, $i, $terse, $columns, $limit); |
| 47 | +function listConcepts($langs, $concepts) { |
| 48 | + foreach ($concepts as $row) { |
| 49 | + printConceptEntry($langs, $row); |
60 | 50 | } |
61 | | - ?> |
62 | | - </table> |
63 | | - <?php |
64 | | - |
65 | | - return $i < $c; |
66 | 51 | } |
67 | 52 | |
68 | | -function printConceptImageRow($images, $from, $terse, $columns = 5, $limit = false) { |
69 | | - global $wwThumbSize, $utils; |
70 | | - |
71 | | - $cw = $wwThumbSize + 32; //FIXME: magic number, use config! |
72 | | - $cwcss = $cw . "px"; |
73 | | - |
74 | | - $to = $from + $columns; |
75 | | - if ( $to > $limit ) $to = $limit; |
76 | | - |
77 | | - print "\t<tr class=\"imageRow\">\n"; |
78 | | - |
79 | | - for ($i = $from; $i<$to; $i += 1) { |
80 | | - $img = $images[$i]; |
81 | | - print "\t\t<td class=\"imageCell\" width=\"$cw\" align=\"left\" valign=\"bottom\" nowrap=\"nowrap\" style=\"width: $cwcss\"><div class=\"clipBox\" style=\"width:$cwcss; max-width:$cwcss;\">"; |
82 | | - print $utils->getThumbnailHTML($img, $wwThumbSize, $wwThumbSize); |
83 | | - print "</div></td>\n"; |
84 | | - } |
85 | | - |
86 | | - print "\n\t</tr>\n"; |
87 | | - |
88 | | - if (!$terse) { |
89 | | - print "\t<tr class=\"imageMetaRow\">\n"; |
90 | | - |
91 | | - for ($i = $from; $i<$to; $i += 1) { |
92 | | - $img = $images[$i]; |
93 | | - |
94 | | - $title = $img['name']; |
95 | | - $title = str_replace("_", " ", $title); |
96 | | - $title = preg_replace("/\\.[^.]+$/", "", $title); |
97 | | - |
98 | | - $info = getImageInfo($img); |
99 | | - $labels = getImageLabels($img); |
100 | | - |
101 | | - print "\t\t<td class=\"imageMetaCell\" width=\"$cw\" align=\"left\" valign=\"top\" style=\"width: $cwcss\"><div class=\"clipBox\" style=\"width:$cwcss; max-width:$cwcss;\">"; |
102 | | - print "<div class=\"imageTitle\" title=\"" . htmlspecialchars( $img['name'] ) . "\">" . htmlspecialchars( $title ) . "</div>"; |
103 | | - |
104 | | - if ($info) { |
105 | | - print "<div class=\"imageInfo\">"; |
106 | | - printList($info, false, "terselist"); |
107 | | - print "</div>"; |
108 | | - } |
109 | | - |
110 | | - if ($labels) { |
111 | | - print "<div class=\"imageLabels\">"; |
112 | | - printList($labels, false, "terselist"); |
113 | | - print "</div>"; |
114 | | - } |
115 | | - |
116 | | - print "</div></td>\n"; |
117 | | - } |
118 | | - |
119 | | - print "\n\t</tr>\n"; |
120 | | - } |
121 | | - |
122 | | - return $to; |
123 | | -} |
124 | | - |
125 | | -function getConceptDetailsLink($langs, $concept, $text = NULL) { |
126 | | - global $utils; |
127 | | - |
128 | | - $name = $utils->pickLocal($concept['name'], $langs); |
129 | | - if ( $name === false || $name === null) return false; |
130 | | - |
131 | | - $name = str_replace("_", " ", $name); |
132 | | - $score = @$concept['score']; |
133 | | - |
134 | | - if ($text === null) $text = $name; |
135 | | - |
136 | | - $u = getConceptDetailsURL($langs, $concept); |
137 | | - return '<a href="' . htmlspecialchars($u) . '" title="' . htmlspecialchars($name) . ' (score: ' . (int)$score . ')'. '">' . htmlspecialchars($text) . '</a>'; |
138 | | -} |
139 | | - |
140 | | -function getConceptPageLinks($lang, $concept) { |
141 | | - $urls = getConceptPageURLs($lang, $concept); |
142 | | - if (!$urls) return false; |
143 | | - |
144 | | - foreach ($urls as $page => $u) { |
145 | | - $links[] = '<a href="' . htmlspecialchars($u) . '" title="' . htmlspecialchars( str_replace("_", " ", $page) ) . '">' . htmlspecialchars( $lang . ":" . str_replace("_", " ", $page) ) . '</a>'; |
146 | | - } |
147 | | - |
148 | | - return $links; |
149 | | -} |
150 | | - |
151 | | -function getAllConceptPageLinks($concept) { |
152 | | - $links = array(); |
153 | | - |
154 | | - foreach ( $concept['languages'] as $lang ) { |
155 | | - $ll = getConceptPageLinks($lang, $concept); |
156 | | - if ($ll) $links[$lang] = $ll; |
157 | | - } |
158 | | - |
159 | | - return $links; |
160 | | -} |
161 | | - |
162 | | -function printList($items, $escape = true, $class = "list") { |
163 | | - ?> |
164 | | - <ul class="<?php print htmlspecialchars($class); ?>"> |
165 | | - <?php |
166 | | - foreach ($items as $item) { |
167 | | - if ( !$item ) continue; |
168 | | - if ( $escape ) $item = htmlspecialchars($item); |
169 | | - print "<li>" . trim($item) . "</li>"; |
170 | | - } |
171 | | - ?> |
172 | | - </ul> |
173 | | - <?php |
174 | | -} |
175 | | - |
176 | | -function printConceptPageList( $langs, $concept, $class, $limit = false ) { |
177 | | - $linksByLanguage = getAllConceptPageLinks($concept); |
178 | | - |
179 | | - $i = 0; |
180 | | - $more = false; |
181 | | - ?> |
182 | | - <ul class="<?php print htmlspecialchars($class); ?>"> |
183 | | - <?php |
184 | | - foreach ( $linksByLanguage as $lang => $links ) { |
185 | | - foreach ($links as $link ) { |
186 | | - print "<li>" . trim($link) . "</li>"; |
187 | | - |
188 | | - $i += 1; |
189 | | - if ($limit && $i >= $limit) break; |
190 | | - } |
191 | | - |
192 | | - if ($limit && $i >= $limit) { |
193 | | - $more = true; |
194 | | - break; |
195 | | - } |
196 | | - } |
197 | | - ?> |
198 | | - </ul> |
199 | | - <?php |
200 | | - |
201 | | - return $more; |
202 | | -} |
203 | | - |
204 | | - |
205 | | -function printDefList($items, $scapeKeys = true, $escapeValues = true, $class = "list") { |
206 | | - ?> |
207 | | - <dl class="<?php print htmlspecialchars($class); ?>"> |
208 | | - <?php |
209 | | - foreach ($items as $key => $item) { |
210 | | - if ( $escapeKeys ) $key = htmlspecialchars($key); |
211 | | - print "\t\t<dt>" . $key . "</dt>\n"; |
212 | | - |
213 | | - if ( $escapeValues ) $item = htmlspecialchars($item); |
214 | | - print "\t\t\t<dd>" . $item . "</dd>\n"; |
215 | | - } |
216 | | - ?> |
217 | | - </sl> |
218 | | - <?php |
219 | | -} |
220 | | - |
221 | | -function getWeightClass($weight) { |
222 | | - if (!isset($weight) || !$weight) { |
223 | | - return "unknown"; |
224 | | - $weight = NULL; |
225 | | - } |
226 | | - else if ($weight>1000) return "huge"; |
227 | | - else if ($weight>100) return "big"; |
228 | | - else if ($weight>10) return "normal"; |
229 | | - else if ($weight>2) return "some"; |
230 | | - else return "little"; |
231 | | -} |
232 | | - |
233 | | - |
234 | | -function printConcept($concept, $langs, $terse = true) { |
235 | | - global $utils, $wwMaxPreviewImages, $wwMaxGalleryImages, $wwMaxPreviewLinks, $wwMaxDetailLinks, $wwGalleryColumns; |
236 | | - |
237 | | - extract( $concept ); |
238 | | - if (@$score) $wclass = getWeightClass($score); |
239 | | - else $wclass = ""; |
240 | | - |
241 | | - #$lclass = $terse ? "terselist" : "list"; |
242 | | - $lclass = "terselist"; |
243 | | - |
244 | | - $name = $utils->pickLocal($concept['name'], $langs); |
245 | | - $name = str_replace("_", " ", $name); |
246 | | - |
247 | | - $gallery = getImagesAbout($concept, $terse ? $wwMaxPreviewImages*2 : $wwMaxGalleryImages+1 ); |
248 | | - |
249 | | - if (empty($definition)) $definition = ""; |
250 | | - else if (is_array($definition)) $definition = $utils->pickLocal($definition, $langs); |
251 | | - |
252 | | - ?> |
253 | | - <tr class="row_head"> |
254 | | - <td colspan="3"> |
255 | | - <h1 class="name <?php print "weight_$wclass"; ?>"><?php print getConceptDetailsLink($langs, $concept); ?>:</h1> |
256 | | - <p class="definition"><?php print htmlspecialchars($definition); ?></p> |
257 | | - </td> |
258 | | - </tr> |
259 | | - |
260 | | - <tr class="row_images"> |
261 | | - <td class="cell_images" colspan="2"> |
262 | | - <?php |
263 | | - if (!$gallery) print "<p class=\"notice\">No images found for concept <em>".htmlspecialchars($name)."</em>.</p>"; |
264 | | - else $more = printConceptImageList( $gallery, $terse, $wwGalleryColumns, $terse ? $wwMaxPreviewImages : $wwMaxGalleryImages ); |
265 | | - ?> |
266 | | - </td> |
267 | | - <?php if ($gallery) { ?> |
268 | | - <td class="cell_more_images" colspan="1" width="100%" style="vertical-align:bottom; padding: 1ex; font-size:normal;"> |
269 | | - <?php if ($terse) print " <div><strong class=\"more\">[" . getConceptDetailsLink($langs, $concept, "more/details...") . "]</strong></div>"; ?> |
270 | | - </td> |
271 | | - <?php } ?> |
272 | | - </tr> |
273 | | - |
274 | | - <?php if (@$concept['narrower']) { ?> |
275 | | - <tr class="row_narrower"> |
276 | | - <td class="cell_related" colspan="3"> |
277 | | - <strong class="label">Narrower:</strong> |
278 | | - <?php |
279 | | - $more = printConceptList( $langs, $concept['narrower'], $lclass, $terse ? $wwMaxPreviewLinks : $wwMaxDetailLinks ); |
280 | | - ?> |
281 | | - <?php if ($terse && $more) print " <strong class=\"more\">[" . getConceptDetailsLink($langs, $concept, "more...") . "]</strong>"; ?> |
282 | | - </td> |
283 | | - </tr> |
284 | | - <?php } ?> |
285 | | - |
286 | | - <?php |
287 | | - $related = getRelatedConceptList($concept); |
288 | | - if ($related) { |
289 | | - ?> |
290 | | - <tr class="row_related"> |
291 | | - <td class="cell_related" colspan="3"> |
292 | | - <strong class="label">Related:</strong> |
293 | | - <?php |
294 | | - $more = printConceptList( $langs, $related, $lclass, $terse ? $wwMaxPreviewLinks : $wwMaxDetailLinks ); |
295 | | - ?> |
296 | | - <?php if ($terse && $more) print " <strong class=\"more\">[" . getConceptDetailsLink($langs, $concept, "more...") . "]</strong>"; ?> |
297 | | - </td> |
298 | | - </tr> |
299 | | - <?php } ?> |
300 | | - |
301 | | - <?php if (@$concept['broader']) { ?> |
302 | | - <tr class="row_category"> |
303 | | - <td class="cell_related" colspan="3"> |
304 | | - <strong class="label">Broader:</strong> |
305 | | - <?php |
306 | | - $more = printConceptList( $langs, $concept['broader'], $lclass, $terse ? $wwMaxPreviewLinks : $wwMaxDetailLinks ); |
307 | | - ?> |
308 | | - <?php if ($terse && $more) print " <strong class=\"more\">[" . getConceptDetailsLink($langs, $concept, "more...") . "]</strong>"; ?> |
309 | | - </td> |
310 | | - </tr> |
311 | | - <?php } ?> |
312 | | - |
313 | | - <?php if (!$terse && @$concept['pages']) { ?> |
314 | | - <tr class="row_pages"> |
315 | | - <td class="cell_pages wikipages" colspan="3"> |
316 | | - <strong class="label">Wiki pages:</strong> <?php $more = printConceptPageList( $langs, $concept, $lclass, $terse ? $wwMaxPreviewLinks : $wwMaxDetailLinks ); ?> |
317 | | - <?php if ($terse && $more) print " <strong class=\"more\">[" . getConceptDetailsLink($langs, $concept, "more...") . "]</strong>"; ?> |
318 | | - </td> |
319 | | - </tr> |
320 | | - <?php } ?> |
321 | | - |
322 | | - <tr class="row_blank"> |
323 | | - <td class="cell_blank" colspan="3"> |
324 | | - |
325 | | - </td> |
326 | | - </tr> |
327 | | - |
328 | | - <?php |
329 | | - if (isset($score) && $score && $score<2 && $pos>=3) return false; |
330 | | - else return true; |
331 | | -} |
332 | | - |
333 | 53 | if( @$_GET( 'ctype' ) == 'application/xml' ) { |
334 | 54 | // Makes testing tweaks about a billion times easier |
335 | 55 | $ctype = 'application/xml'; |
— | — | @@ -336,15 +56,62 @@ |
337 | 57 | $ctype = 'application/atom+xml'; |
338 | 58 | } |
339 | 59 | |
| 60 | +if (!isset($wwDbDate)) $wwDbDate = date("Y-m-d H:i:s T"); |
| 61 | + |
340 | 62 | if (!isset($scriptPath)) $scriptPath = "./"; |
341 | 63 | if (!isset($skinPath)) $skinPath = "$scriptPath/../skin/"; |
342 | 64 | |
| 65 | +$uri = "$scriptPath/search.php?lang=".urlencode($lang)."&format=atom"; |
| 66 | + |
| 67 | +if ($mode == 'term') { |
| 68 | + $search = "$lang:$term"; |
| 69 | + $uri .= "&term=".urlencode(term); |
| 70 | + $title = $term; |
| 71 | +} else if ($mode == 'concept') { |
| 72 | + $term = "\${$conceptId}"; |
| 73 | + $search = "$lang:$term"; |
| 74 | + $uri .= "&id=".urlencode($conceptId); |
| 75 | + |
| 76 | + $keys = array_keys($result); |
| 77 | + $k = $keys[0]; |
| 78 | + $concept = $result[$k]; |
| 79 | + $title = $utils->pickLocal($concept['name'], $langs); |
| 80 | +} |
| 81 | + |
343 | 82 | header("Content-Type: $ctype; charset=$ctype"); |
344 | 83 | ?><?xml version="1.0" encoding="UTF-8"?> |
345 | 84 | <feed xmlns="http://www.w3.org/2005/Atom" |
346 | 85 | xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"> |
| 86 | + |
347 | 87 | <link rel="search" |
348 | 88 | href="http://example.com/opensearchdescription.xml" |
349 | 89 | type="application/opensearchdescription+xml" |
350 | | - title="Content Search" /> |
| 90 | + title="WikiPics Search" /> |
| 91 | + |
| 92 | + <title><?php print htmlspecialchars("$title ($lang) WikiPics"); ?></title> |
| 93 | + <link rel="self" href="<?php print htmlspecialchars($uri); ?>"/> |
| 94 | + <updated><?php print htmlspecialchars($wwDbDate); ?></updated> |
| 95 | + <author> |
| 96 | + <name><?php print htmlspecialchars($wwDbAuthor); ?></name> |
| 97 | + </author> |
| 98 | + <icon><?php print htmlspecialchars("$skinPath/favicon.ico"); ?></icon> |
| 99 | + <logo><?php print htmlspecialchars("$skinPath/wikipics.png"); ?></logo> |
| 100 | + <generator>WikiPics 0.1α (experimental)</generator> |
| 101 | + <id>sha1:<?php print sha1("$search/$date"); ?></id> |
| 102 | + <opensearch:totalResults><?php print count($result); ?></opensearch:totalResults> |
| 103 | + <opensearch:startIndex>1</opensearch:startIndex> |
| 104 | + <opensearch:itemsPerPage>100</opensearch:itemsPerPage> |
| 105 | + <opensearch:Query role="request" language="<?php print htmlspecialchars($lang); ?>" searchTerms="<?php print htmlspecialchars($lang); ?>" startPage="1" /> |
| 106 | + |
| 107 | + |
| 108 | + <?php |
| 109 | + if ($error) { |
| 110 | + reportError($error); |
| 111 | + } else if ($mode=='concept') { |
| 112 | + listConceptImages($concept); |
| 113 | + listRelatedConcepts($concept); |
| 114 | + } if ($mode=='term') else { |
| 115 | + listConcepts($languages, $result); |
| 116 | + } |
| 117 | + ?> |
351 | 118 | </xml> |
Index: trunk/WikiWord/WikiWordWeb/src/main/www/wikipics/response.html.php |
— | — | @@ -346,7 +346,7 @@ |
347 | 347 | </head> |
348 | 348 | <body> |
349 | 349 | <div class="header"> |
350 | | - <div style="float:left">Wikipics 0.1α (experimental)</div> |
| 350 | + <div style="float:left">WikiPics 0.1α (experimental)</div> |
351 | 351 | <div style="float:right"><a href="http://wikimedia.de">Wikimedia Deutschland e.V.</a></div> |
352 | 352 | <!-- <h1>WikiWord Navigator</h1> |
353 | 353 | <p>Experimental semantic navigator and thesaurus interface for Wikipedia.</p> |
— | — | @@ -361,8 +361,8 @@ |
362 | 362 | } |
363 | 363 | |
364 | 364 | if (!$result && $mode) { |
365 | | - if ($mode=="concept") print "<p class=\"error\">".htmlspecialchars($error)."</p>"; |
366 | | - else if ($mode=="term") print "<p class=\"notice\">No meanings found for term <em>".htmlspecialchars($term)."</em>.</p>"; |
| 365 | + if ($mode=="concept") print "<p class=\"notice\">Concept not found: <em>".htmlspecialchars($lang).":$".htmlspecialchars($concept)."</em></p>"; |
| 366 | + else if ($mode=="term") print "<p class=\"notice\">No meanings found for term <em>".htmlspecialchars($lang).":".htmlspecialchars($term)."</em>.</p>"; |
367 | 367 | } |
368 | 368 | ?> |
369 | 369 | |
Index: trunk/WikiWord/WikiWordWeb/src/main/www/common/wwutils.php |
— | — | @@ -155,13 +155,19 @@ |
156 | 156 | } |
157 | 157 | |
158 | 158 | function pickLocal($items, $languages) { |
159 | | - if ( is_string($languages) ) $languages = array( $languages, "en", "commons" ); |
160 | | - |
161 | | - foreach ($languages as $lang) { |
162 | | - if (isset($items[$lang])) return $items[$lang]; |
163 | | - } |
| 159 | + $lang = $this->pickLanguage($items, $languages); |
| 160 | + if (!$lang) return false; |
| 161 | + return $items[$lang]; |
| 162 | + } |
164 | 163 | |
165 | | - return false; |
| 164 | + function pickLanguage($items, $languages) { |
| 165 | + if ( is_string($languages) ) $languages = array( $languages, "en", "commons" ); |
| 166 | + |
| 167 | + foreach ($languages as $lang) { |
| 168 | + if (isset($items[$lang])) return $lang; |
| 169 | + } |
| 170 | + |
| 171 | + return false; |
166 | 172 | } |
167 | 173 | |
168 | 174 | static function authFailed($realm) { |