Project

General

Profile

Download (19.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Page theming functions.
5
 *
6
 * @copyright
7
 *   (C) 2007-2012 EDIT
8
 *   European Distributed Institute of Taxonomy
9
 *   http://www.e-taxonomy.eu
10
 *
11
 *   The contents of this module are subject to the Mozilla
12
 *   Public License Version 1.1.
13
 * @see http://www.mozilla.org/MPL/MPL-1.1.html
14
 */
15

    
16
/**
17
 * Returns HTML for the default title of a taxon page.
18
 *  * The returned title is a formatted taxon name.
19
 *
20
 * @param array $variables
21
 *   An associative array containing:
22
 *   - taxon: The taxon name being formatted for the title.
23
 *   - uuid: UUID for the taxon.
24
 *
25
 * @ingroup themeable
26
 */
27
function theme_cdm_taxon_page_title($variables) {
28
  $taxon = $variables['taxon'];
29
  RenderHints::pushToRenderStack('taxon_page_title');
30
  $referenceUri = '';
31
  $out = '';
32
  if (isset($taxon->name->nomenclaturalReference)) {
33
    $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
34
  }
35

    
36
  $out .= render_taxon_or_name($taxon, NULL, $referenceUri, FALSE);
37
  RenderHints::popFromRenderStack();
38

    
39
  return '<span class="' . $taxon->class . '">' . $out . '</span>';
40
}
41

    
42
/**
43
 * Returns HTML for the default title of a specimen page.
44
 *  * The returned title is a the identifier of the specimen.
45
 *
46
 * @param array $variables
47
 *   An associative array containing:
48
 *   - specimen: The specimen being formatted for the title.
49
 *
50
 * @ingroup themeable
51
 */
52
function theme_cdm_specimen_page_title($variables) {
53
    $specimen = $variables['specimen'];
54
    RenderHints::pushToRenderStack('specimen_page_title');
55
    $referenceUri = '';
56
    $out = '';
57

    
58
    $title = "";
59
    if($specimen->accessionNumber){
60
        $title = $specimen->accessionNumber;
61
    }
62
    elseif($specimen->barcode){
63
        $title = $specimen->barcode;
64
    }
65
    elseif($specimen->catalogNumber) {
66
        $title = $specimen->catalogNumber;
67
    }
68

    
69

    
70
  $out .= $title;
71
  RenderHints::popFromRenderStack();
72

    
73
  return '<span class="' . $specimen->class . '">' . $out . '</span>';
74
}
75

    
76
/**
77
 * Returns HTML for the default title for a name page.
78
 *
79
 * The returned title is a formatted name.
80
 *
81
 * @param array $variables
82
 *   An associative array containing:
83
 *   - taxon_name: The taxon name object.
84
 *
85
 * @ingroup themeable
86
 */
87
function theme_cdm_name_page_title($variables) {
88
  $taxon_name = $variables['taxon_name'];
89
  RenderHints::pushToRenderStack('taxon_page_title');
90

    
91
  $referenceUri = NULL;
92
  if (isset($taxon_name->nomenclaturalReference)) {
93
    $referenceUri = url(path_to_reference($taxon_name->nomenclaturalReference->uuid));
94
  }
95

    
96
  $out = '<span class="' . $taxon_name->class . '">'
97
    . render_taxon_or_name($taxon_name, NULL, $referenceUri, FALSE)
98
    . '</span>';
99
  RenderHints::popFromRenderStack();
100
  return $out;
101
}
102

    
103

    
104

    
105

    
106

    
107
/**
108
 * Returns HTML containing the synonymy for the accepted taxon.
109
 *
110
 * Shows the whole synonymy for the accepted taxon.
111
 * The synonymy list is headed by the complete scientific name
112
 * of the accepted taxon with nomenclatural reference.
113
 *
114
 * @param array $variables
115
 *   An associative array containing:
116
 *   - taxon
117
 *   - addAcceptedTaxon
118
 *
119
 * @ingroup themeable
120
 */
121
function theme_cdm_taxon_page_synonymy($variables) {
122
  $taxon = $variables['taxon'];
123
  $addAcceptedTaxon = $variables['addAcceptedTaxon'];
124

    
125
  RenderHints::pushToRenderStack('taxon_page_synonymy');
126

    
127
  // footnote key for the homotypic group and accepted taxon,
128
  // both should have the same footnote key
129
  RenderHints::setFootnoteListKey(RenderHints::getRenderPath());
130

    
131
  $synomymie = cdm_ws_get(CDM_WS_PORTAL_TAXON_SYNONYMY, $taxon->uuid);
132
  $skip = array(
133
    UUID_NAMERELATIONSHIPTYPE_BASIONYM,
134
  );
135
  $out = '';
136

    
137
  // Render accepted taxon.
138
  //
139
  // foonotes of the accepted taxon will be rendered in the homotypic group section
140
  // even if there are not synonyms in the homotypic group
141
  // homotypic group and accepted taxon should have the same footnote key
142
  $referenceUri = '';
143
  if ($addAcceptedTaxon) {
144
    // remember the last part of the render path
145
    $synonymy_render_path = RenderHints::getRenderPath();
146
    // set new render path for the accepted taxon so
147
    // it can be styled differently via the name render part definitions
148
    RenderHints::pushToRenderStack('accepted_taxon');
149
    if (isset($taxon->name->nomenclaturalReference)) {
150
      $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
151
    }
152

    
153
    $accepted_name = '<div class="accepted-name">';
154
    $accepted_name .= render_taxon_or_name($taxon, NULL, $referenceUri);
155

    
156
    $name_relationships = cdm_name_relationships_of($taxon);
157
    // Render relationships of accepted name.
158
    if($name_relationships){
159

    
160
      $accepted_name .= ' <span class="name_relationships">' . $name_relationships . '</span>';
161
    }
162

    
163
      // handle annotations of the name and taxon
164
    $special_annotations_array = array();
165
    $special_annotations_array[] = $taxon->name;
166
    $special_annotations_array[] = $taxon;
167
    $accepted_name .= theme('cdm_annotations_as_footnotekeys', array(
168
        'cdmBase_list' => $special_annotations_array,
169
        'footnote_list_key' => $synonymy_render_path . '-annotations')
170
      );
171
    $accepted_name .= '</div>';
172
    RenderHints::popFromRenderStack();
173
  }
174

    
175
  // --- Render homotypic synonymy group
176
  if (!empty($accepted_name)) {
177
    $out .= $accepted_name;
178
  }
179

    
180
  // Render the homotypicSynonymyGroup including the type information.
181
  $out .= theme(
182
      'cdm_homotypicSynonymyGroup',
183
      array(
184
          'synonymList' => $synomymie->homotypicSynonymsByHomotypicGroup,
185
          'accepted_taxon_name_uuid' => $taxon->name->uuid
186
      )
187
    );
188

    
189

    
190
  // Render accepted taxon heterotypic synonymy groups.
191
  if ($synomymie->heterotypicSynonymyGroups) {
192
    foreach ($synomymie->heterotypicSynonymyGroups as $homotypicalGroup) {
193
      $out .= theme('cdm_heterotypicSynonymyGroup', array('homotypicalGroup' => $homotypicalGroup));
194
    }
195
  }
196
  // Render taxon relationships.
197
  if (variable_get(CDM_DATAPORTAL_DISPLAY_TAXON_RELATIONSHIPS, CDM_DATAPORTAL_DISPLAY_TAXON_RELATIONSHIPS_DEFAULT)) {
198
    $taxonRelationships = cdm_ws_get(CDM_WS_PORTAL_TAXON_RELATIONS, $taxon->uuid);
199
    $out .= cdm_taxonRelationships($taxonRelationships, $taxon);
200
  }
201

    
202
  RenderHints::popFromRenderStack();
203

    
204
  return $out;
205
}
206

    
207

    
208
/**
209
 * Returns HTML for the given result page including a pager.
210
 *
211
 * @param array $variables
212
 *   An associative array containing:
213
 *   - pager: The cdmlib pager object containing the result set of cdm base
214
 *     objects (currently this function can only handle taxon instances =>
215
 *     TODO)
216
 *   - path: The target path for the pager links, this will usually point to
217
 *     'cdm_dataportal/search/results/taxon'
218
 *
219
 * @ingroup themeable
220
 */
221
function theme_cdm_search_results($variables)
222
{
223
  $pager = $variables['pager'];
224
  $path = $variables['path'];
225

    
226
  $freetextSearchResults = array();
227

    
228
  // If the pager contains records of SearchResults, extract the taxa and use
229
  // them as records instead.
230
  if (isset($pager->records[0]) && $pager->records[0]->class == "SearchResult") {
231
    $freetextSearchResults = $pager->records;
232
    $taxa = array();
233
    // $highlightedFragments = array();
234
    foreach ($pager->records as $searchResult) {
235
      $taxa[] = &$searchResult->entity;
236
      /*
237
       if(!isset($searchResult->fieldHighlightMap)){
238
      $searchResult->fieldHighlightMap = NULL;
239
      }
240
      $fragmentHighlighting[] = $searchResult->fieldHighlightMap;
241
      */
242
    }
243
    $pager->records = $taxa;
244
  }
245

    
246

    
247
  // Add thumbnails checkbox and refine search link.
248
  $out = '<div class="page_options">';
249
  if (isset($_REQUEST['ws'])) {
250
    if (cdm_dataportal_search_form_path_for_ws($_REQUEST['ws'])) {
251
      $out .= '<div id="backButton">' . l(t('Modify search'), cdm_dataportal_search_form_path_for_ws($_REQUEST['ws'])) . '</div>';
252
    }
253
  }
254
  if (variable_get(SEARCH_RESULTS_SHOW_THUMBNAIL_CHECKBOX, SEARCH_RESULTS_SHOW_THUMBNAIL_CHECKBOX_DEFAULT)) {
255
    $out .= '<form name="pageoptions"><div id="showThumbnails"><input class="showThumbnails" type="checkbox" name="showThumbnails" ' . (do_showThumbnails() == 1 ? 'checked="checked"' : '') . '> ' . t('Display Image Thumbnails') . '</div></form>';
256
  }
257
  $out .= '</div>';
258

    
259
  $classification = cdm_dataportal_searched_in_classification();
260

    
261

    
262
  if (  count(cdm_ws_fetch_all(CDM_WS_PORTAL_TAXONOMY)) > 1 ) { // FIXME use a count REST method for this!!!
263
    $out .= '<div id="search-summary">' . t('results for') . ' ';
264
    if ($classification != NULL) {
265
      $out .=  $classification->titleCache ;
266
    } else {
267
     $out .= t('any classification');
268
    }
269
    $out .= ':</div>';
270
  }
271

    
272
  // List results.
273
  if (isset($pager->records) && count($pager->records) > 0) {
274
    $out .= '<div id="search_results">';
275
    $out .= theme('cdm_list_of_taxa',
276
        array(
277
          'records' => $pager->records,
278
          'freetextSearchResults' => $freetextSearchResults,
279
          'show_classification' => $classification === NULL
280
        )
281
      );
282
    $out .= '</div>';
283
    $out .= theme('cdm_pager', array(
284
        'pager' => $pager,
285
        'path' => $path,
286
        'parameters' => $_REQUEST,
287
    ));
288
  } else {
289
    $out .= '<h4 class="error">Sorry, no matching entries found.</h4>';
290
  }
291
  return $out;
292
}
293

    
294

    
295
/**
296
 * TODO Implementation of Hook taxon_image_gallery()
297
 *
298
 * @param unknown_type $taxon
299
 * @param unknown_type $media
300
 *
301
 * @return unknown_type
302
 */
303
function taxon_image_gallery_default($taxon, $media) {
304
  $hasImages = isset($media[0]);
305

    
306
  if ($hasImages) {
307

    
308
    $maxExtend = 150;
309
    $cols = 3;
310
    $maxRows = FALSE;
311
    $alternativeMediaUri = NULL;
312
    /* Comment @WA: was in D5:
313
    $captionElements = array(
314
      'title',
315
      'rights',
316
      '#uri' => t('open Image'),
317
    );
318
    */
319
    $captionElements = array(
320
      'title',
321
      'description',
322
      'artist',
323
      'location',
324
      'rights',
325
      '#uri' => t('open Image'),
326
    );
327
    $gallery_name = $taxon->uuid;
328
    $mediaLinkType = 'LIGHTBOX';
329

    
330
    // $gallery_settings = getGallerySettings(CDM_DATAPORTAL_MEDIA_GALLERY_NAME);
331

    
332
    $gallery_settings = getGallerySettings(CDM_DATAPORTAL_TAXON_MEDIA_GALLERY_NAME_TAB);
333

    
334
    $out = '<div class="image-gallerie">';
335
    $out .= theme('cdm_media_gallerie', array(
336
      'mediaList' => $media,
337
      'galleryName' => $gallery_name,
338
      'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
339
      'cols' => $gallery_settings['cdm_dataportal_media_cols'],
340
      'maxRows' => 0, // Ignore maxrows settings.
341
      'captionElements' => $captionElements,
342
      'mediaLinkType' => $mediaLinkType,
343
      'alternativeMediaUri' => NULL,
344
      'galleryLinkUri' => NULL,
345
      'showCaption' => $gallery_settings['cdm_dataportal_show_thumbnail_captions'],
346
    ));
347
    $out .= '</div>';
348
  }
349
  else {
350
    $out = 'No images available.';
351
  }
352
  return $out;
353
}
354

    
355
/**
356
 * TODO Implementation of Hook taxon_image_gallery()
357
 *
358
 * @param unknown_type $taxon
359
 * @param unknown_type $media
360
 *
361
 * @return unknown_type
362
 */
363
function taxon_image_gallery_fsi($taxon, $media) {
364
  $flashLink = isset($media[0]);
365

    
366
  if ($flashLink) {
367

    
368
    if (module_exists("fsi_gallery")) {
369
      $out = theme("fsi_gallery", array('taxon' => $taxon, 'media' => $media));
370
    }
371
    else {
372
      $message = t('In order to use the FSI gallery you must enable the according ') . l(t("module"), "admin/modules");
373
      drupal_set_message($message, "error");
374
      $out = '<h3>' . $message . '</h3>';
375
    }
376
  }
377
  else {
378
    $out = 'No images available.';
379
  }
380
  return $out;
381
}
382

    
383
/**
384
 * Returns HTML for a single reference page.
385
 *
386
 * Renders a page with all data on a single reference.
387
 *
388
 * @param array $variables
389
 *   An associative array containing:
390
 *   - reference: Object.
391
 *
392
 * @ingroup themeable
393
 */
394
function theme_cdm_reference_page($variables) {
395
  $reference = $variables['reference'];
396

    
397
  $out = '';
398

    
399
  if (isset($reference->titleCache)) {
400
    drupal_set_title($reference->titleCache, PASS_THROUGH);
401
  }
402

    
403
  $field_order = array(
404
    "title",
405
    // "titleCache",
406
    // "citation",
407
    "authorship",
408
    "editor",
409
    "publisher",
410
    "placePublished",
411
    "datePublished",
412
    "year",
413
    "edition",// Class Book.
414
    "volume",// Class Article.
415
    "seriesPart",
416
    "inReference",
417
    "nomRefBase", // Class BookSection, Book, Article.
418
    "pages",// Class Article.
419
    "series",// Class Article, PrintSeries.
420
    "school",// Class Thesis.
421
    "institution",// Class Report.
422
    "organization",// Class Proceedings.
423
    "nextVersion",
424
    "previousVersion",
425
    "isbn",// Class Book.
426
    "issn",// Class Journal.
427
    "uri",
428
  );
429

    
430
  $header = array(
431
    t('Field'),
432
    t('Value'),
433
  );
434
  $table_rows = array();
435

    
436
  if (!isset($reference->authorship)) {
437
    $authorship = cdm_ws_get(CDM_WS_REFERENCE_AUTHORTEAM, $reference->uuid);
438
    $reference->authorship = isset($authorship->titleCache) ? $authorship->titleCache : '';
439
  }
440

    
441
  if (!isset($reference->inReference)) {
442
    $reference->inReference = cdm_ws_get(CDM_WS_REFERENCE, array(
443
      $reference->uuid,
444
      "inReference",
445
    ));
446
  }
447

    
448
  foreach ($field_order as $fieldname) {
449

    
450
    if (isset($reference->$fieldname)) {
451

    
452
      if ($fieldname == "datePublished") {
453
        $period = $reference->$fieldname;
454
        $datePublished = timePeriodToString($period);
455
        if (isset($datePublished) && $datePublished != '') {
456
          $table_rows[] = array(
457
            t(ucfirst(strtolower($fieldname))),
458
            $datePublished,
459
          );
460
        }
461
        // $datePublished = array(t(ucfirst(strtolower($fieldname))),
462
        // $datePublished);
463
      }
464
      elseif (is_object($reference->$fieldname)) {
465
        if ($fieldname == "authorship") {
466
          $dump = $reference->$fieldname;
467
          $teammembers = "teamMembers";
468
          $team = $dump->$teammembers;
469
          $nameArray = array();
470

    
471
          foreach ($team as $member) {
472
            if (strlen($member->lastname) > 0) {
473
              $nname = $member->lastname;
474
              $name = $nname;
475
              if (strlen($member->firstname) > 0) {
476
                $vname = $member->firstname;
477
                $name = $vname . " " . $nname;
478
              }
479
              $nameArray[] = $name;
480
            }
481
            else {
482
              if (strlen($member->titleCache) > 0) {
483
                $nameArray[] = $member->titleCache;
484
              }
485
            }
486
          }
487
          $value = join($nameArray, ", ");
488
        }
489
        elseif ($fieldname == "inReference") {
490
          $type = $reference->$fieldname->type;
491
          $value = l($reference->$fieldname->titleCache, path_to_reference($reference->$fieldname->uuid));
492
          switch ($type) {
493
            case "Book":
494
              $fieldname = "in book";
495
              break;
496
            case "Journal":
497
              $fieldname = "in journal";
498
              break;
499
            case "Proceedings":
500
              $fieldname = "in proceedings";
501
              break;
502
          }
503
        }
504
        else {
505
          $value = $reference->$fieldname->titleCache;
506
        }
507
        if (isset($value) && $value != '') {
508
          $table_rows[] = array(
509
            t(ucfirst(strtolower($fieldname))),
510
            $value,
511
          );
512
        }
513
      }
514
      else {
515
        if (isset($reference->$fieldname) && $reference->$fieldname != '') {
516
          $table_rows[] = array(
517
            t(ucfirst(strtolower($fieldname))),
518
            $reference->$fieldname,
519
          );
520
        }
521
      }
522
    }
523
  }
524

    
525
  $out = theme_table(array(
526
      'header' => array(),
527
      'rows' => $table_rows,
528
      'attributes' => array(),
529
      'caption' => NULL,
530
      'colgroups' => NULL,
531
      'sticky' => NULL,
532
     'empty' => NULL,
533
  ));
534

    
535
  // Annotations below the table.
536
  $annotations = cdm_ws_getAnnotationsFor($reference);
537
  $out .= theme("cdm_annotations", array('annotations' => $annotations));
538

    
539
  return $out;
540
}
541

    
542
/**
543
 * @todo Please document this function.
544
 * @see http://drupal.org/node/1354
545
 */
546
function theme_cdm_media_page($variables) {
547
  $media = $variables['media'];
548
  $mediarepresentation_uuid = $variables['mediarepresentation_uuid'];
549
  $partId = $variables['partId'];
550
  $out = '';
551
  // Determine which representation and which part to show.
552
  $representationIdx = 0;
553
  if ($mediarepresentation_uuid) {
554
    $i = 0;
555
    foreach ($media->representations as $representation) {
556
      if ($representation->uuid == $mediarepresentation_uuid) {
557
        $representationIdx = $i;
558
      }
559
      $i++;
560
    }
561
  }
562
  else {
563
    $mediarepresentation_uuid = $media->representations[0]->uuid;
564
  }
565

    
566
  $partIdx = 0;
567
  if (!is_numeric($partId)) {
568
    // Assuming it is an uuid.
569
    $i = 0;
570
    foreach ($media->representations[$representationIdx]->parts as $part) {
571
      if ($part->uuid == $partId) {
572
        $partIdx = $i;
573
      }
574
      $i++;
575
    }
576
  }
577
  else {
578
    // Assuming it is an index.
579
    $partIdx = $partId;
580
  }
581

    
582
  $media_metadata = read_media_metadata($media);
583
  // $title = $media->titleCache;
584
  $title = $media_metadata['title'];
585

    
586
  $imageMaxExtend = variable_get('image-page-maxextend', 400);
587

    
588
  if (!$title) {
589
    $title = 'Media ' . $media->uuid . '';
590
  }
591

    
592
  drupal_set_title($title, PASS_THROUGH);
593

    
594
  $out .= '<div class="media cdm_media_viewer_image">';
595

    
596
  $out .= theme('cdm_back_to_image_gallery_button', array());
597
  $out .= '<div class="viewer">';
598
  $out .= theme('cdm_openlayers_image', array('mediaRepresentationPart' => $media->representations[$representationIdx]->parts[$partIdx], 'maxExtend' => $imageMaxExtend));
599
  $out .= '</div>';
600

    
601
  // General media metadata.
602
  /*
603
  $media_metadata = cdm_ws_get(CDM_WS_MEDIA_METADATA, array($media->uuid));
604
  vardump("PRINTING MEDIA METADATA");
605
  vardump($media_metadata);
606
  vardump("PRINTING MEDIA");
607
  vardump($media);
608
  */
609
  $metadataToPrint = theme('cdm_media_caption', array('media' => $media));
610
  $out .= $metadataToPrint;
611

    
612
  // Tabs for the different representations.
613
  // ul.secondary
614
  $out .= '<ul class="primary">';
615
  foreach ($media->representations as $representation) {
616
    $out .= '<li>' . l($media->representations[$representationIdx]->mimeType, path_to_media($media->uuid, $mediarepresentation_uuid, $partIdx)) . '</li>';
617
  }
618
  $out .= '</ul>';
619

    
620
  // Representation(-part) specific metadata.
621
  $thumbnailMaxExtend = 100;
622
  $out .= '<table>';
623
  $i = 0;
624
  foreach ($media->representations[$representationIdx]->parts as $part) {
625
    $out .= '<tr><th>' . t('Part') . ' ' . ($i + 1) . '</th><td>';
626
    switch ($part->class) {
627
      case 'ImageFile':
628
        $out .= $part->width . ' x ' . $part->height . ' - ' . $part->size . 'k';
629
        break;
630
      case 'AudioFile':
631
      case 'MovieFile':
632
        $out .= t('Duration') . ': ' . $part->duration . 's - ' . $part->size . 'k';
633
        break;
634
      default:
635
        $out .= $part->size . 'k';
636
    }
637

    
638
    $out .= '</td><td><a href="' . url(path_to_media($media->uuid, $mediarepresentation_uuid, $i)) . '">' . theme('cdm_media_gallerie_image', array('mediaRepresentationPart' => $part, 'maxExtend' => $thumbnailMaxExtend, 'addPassePartout' => TRUE));
639
    $i++;
640
  }
641
  $out .= '</table>';
642
  $out .= '</div>';
643

    
644
  return $out;
645
}
646

    
647
/**
648
 * @todo Please document this function.
649
 * @see http://drupal.org/node/1354
650
 */
651
function theme_cdm_polytomousKey_page($variables) {
652
  $polytomousKey = $variables['polytomousKey'];
653
  drupal_set_title($polytomousKey->titleCache, PASS_THROUGH);
654

    
655
  $out = theme("cdm_IdentificationKey", array(
656
    'identificationKey' => $polytomousKey,
657
    'doLinkToKeyPage' => FALSE,
658
    'showIdentificationKeyTitle' => FALSE,
659
    ));
660

    
661
  // Key nodes in linked style.
662
  $out .= theme('cdm_polytomousKey', array('polytomousKey' => $polytomousKey));
663
  /*
664
   * FIXME implement node type for keys !!!
665
   * (wrapping the content in the cdm_dataportal.node becomes obsolete then).
666
   */
667
  return '<div id="identificationKey">' . $out . '</div>';
668
}
669

    
670
/**
671
 * Returns HTML for taxon page tabs.
672
 *
673
 * Allows theming of the taxon page tabs.
674
 *
675
 * @param array $variables
676
 *   An associative array containing:
677
 *   - tabname
678
 *
679
 * @ingroup themeable
680
 */
681
function theme_cdm_taxonpage_tab($variables) {
682
  $tabname = $variables['tabname'];
683
  // TODO replace by using translations or theme the menue tabs itself instead?
684
  switch ($tabname) {
685
    default:
686
      return t($tabname);
687
  }
688
}
(6-6/9)