Entity/TagRepository.php
author cavaliet
Wed, 30 Nov 2011 17:58:18 +0100
changeset 50 e967654e90cb
parent 42 0e57c730bb18
child 59 ea562f37d7a5
permissions -rwxr-xr-x
First step of error management when Wikipedia request fails. Set up in whole list and document list.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
namespace IRI\Bundle\WikiTagBundle\Entity;
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
use Doctrine\ORM\EntityRepository;
42
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
     6
use IRI\Bundle\WikiTagBundle\Utils\WikiTagUtils;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
     7
use IRI\Bundle\WikiTagBundle\Entity\Tag;
2
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
/**
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 * TagRepository
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 *
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
 * This class was generated by the Doctrine ORM. Add your own custom
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
 * repository methods below.
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 */
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
class TagRepository extends EntityRepository
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
{
34
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    17
    public function getTagCloud($max_tags)
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    18
    {
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    19
        $qb = $this->getEntityManager()->createQueryBuilder();
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    20
        $qb->select('t.id', 't.label', 'COUNT( dt.id ) AS nb_docs');
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    21
        $qb->from('WikiTagBundle:Tag','t');
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    22
        $qb->leftJoin('t.documents', 'dt', 'WITH', 't = dt.tag');
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    23
        $qb->addGroupBy('t.id');
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    24
        $qb->addOrderBy('nb_docs','DESC');
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    25
        $qb->setMaxResults($max_tags);
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    26
        
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    27
        $query = $qb->getQuery();
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    28
        return $query->getResult();
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    29
    }
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    30
    
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    31
    public function getCompletion($seed)
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    32
    {
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    33
        $qb = $this->getEntityManager()->createQueryBuilder();
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    34
        $qb->select('t.label');
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    35
        $qb->from('WikiTagBundle:Tag','t');
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    36
        $qb->where($qb->expr()->orx(
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    37
            $qb->expr()->like('t.label',$qb->expr()->literal("%".addcslashes(mysql_real_escape_string($seed),"%_"))),
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    38
            $qb->expr()->like('t.label',$qb->expr()->literal("% ".addcslashes(mysql_real_escape_string($seed),"%_")."%"))
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    39
        ));
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    40
        
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    41
        $query = $qb->getQuery();
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    42
        
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    43
        return $query->getResult();
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    44
        
21fab44f46fe add event on tag changed
ymh <ymh.work@gmail.com>
parents: 2
diff changeset
    45
    }
42
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    46
    
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    47
    /**
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    48
    * Get or create tag. Returns an array(tag:WikiTagTag, revision_id=int, created:Boolean)
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    49
    * @param $tag_label
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    50
    * @param $doctrine
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    51
    * @return multitype:boolean Ambigous <NULL, \IRI\Bundle\WikiTagBundle\Entity\Tag> Ambigous <NULL, unknown, mixed, string> (array(\IRI\Bundle\WikiTagBundle\Model\TagInterface, revision_id=int, created:Boolean))
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    52
    */
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    53
    public function getOrCreateTag($tag_label)
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    54
    {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    55
        $tag_label_normalized = WikiTagUtils::normalizeTag($tag_label);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    56
        // We get the wikipedia references for the tag_label
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    57
        // We get or create the tag object
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    58
        $tags = $this->findBy(array('normalizedLabel' => $tag_label_normalized));
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    59
        $tag = null;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    60
        foreach ($tags as $t) {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    61
            if($tag==null || $t->getUrlStatus()!=Tag::$TAG_URL_STATUS_DICT['null_result']) {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    62
                $tag = $t;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    63
                if($t->getUrlStatus()!=Tag::$TAG_URL_STATUS_DICT['null_result']) {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    64
                    break;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    65
                }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    66
            }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    67
        }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    68
        $wp_request_done = false;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    69
        if($tag==null) {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    70
            $tag = new Tag();
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    71
            $tag->setLabel($tag_label_normalized);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    72
            $tag->setOriginalLabel($tag_label);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    73
            $tag->setNormalizedLabel($tag_label_normalized);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    74
            $created = true;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    75
        }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    76
        else {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    77
            $created = false;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    78
            $match_exists = false;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    79
            // Even if a tag with the normalised label exists, IF this tag is not wikipedia semantised,
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    80
            // we search if a wikipedia semantised version exists in the base
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    81
            foreach ($tags as $t) {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    82
                if($t->getUrlStatus()==Tag::$TAG_URL_STATUS_DICT['match']) {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    83
                    $tag = $t;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    84
                    $match_exists = true;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    85
                    break;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    86
                }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    87
            }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    88
            if($match_exists==false) {
50
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
    89
                try {
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
    90
                    $wp_response = WikiTagUtils::getWikipediaInfo($tag_label_normalized);
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
    91
                }
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
    92
                catch (\Exception $e){
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
    93
                    throw new \Exception($e->getMessage());
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
    94
                }
42
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    95
                $status = $wp_response['status'];
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    96
                if($status==Tag::$TAG_URL_STATUS_DICT['match']) {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    97
                    $tag = new Tag();
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    98
                    $tag->setLabel($tag_label_normalized);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
    99
                    $tag->setOriginalLabel($tag_label);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   100
                    $tag->setNormalizedLabel($tag_label_normalized);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   101
                    $created = true;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   102
                    $wp_request_done = true;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   103
                }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   104
            }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   105
        }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   106
    
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   107
        // We request Wikipedia if the tag is created
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   108
        if($created==true) {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   109
            
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   110
            if($wp_request_done==false) {
50
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   111
                try {
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   112
                    $wp_response = WikiTagUtils::getWikipediaInfo($tag_label_normalized);
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   113
                }
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   114
                catch (\Exception $e){
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   115
                    throw new \Exception($e->getMessage());
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   116
                }
42
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   117
            }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   118
            
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   119
            $tag->setWikipediaInfo($wp_response);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   120
    
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   121
            // Save datas.
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   122
            $em = $this->getEntityManager();
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   123
            $em->persist($tag);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   124
            $em->flush();
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   125
                
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   126
            $wikipedia_revision_id = $wp_response['revision_id'];
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   127
    
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   128
        }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   129
        else if($tag!=null && $tag->getWikipediaPageId()!=null) {
50
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   130
            try {
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   131
                $wp_response = WikiTagUtils::getWikipediaInfo(null, $tag->getWikipediaPageId());
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   132
            }
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   133
            catch (\Exception $e){
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   134
                throw new \Exception($e->getMessage());
e967654e90cb First step of error management when Wikipedia request fails. Set up in whole list and document list.
cavaliet
parents: 42
diff changeset
   135
            }
42
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   136
            $wikipedia_revision_id = $wp_response['revision_id'];
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   137
        }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   138
        else {
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   139
            $wikipedia_revision_id = null;
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   140
        }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   141
    
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   142
        return array($tag, $wikipedia_revision_id, $created);//, $wpReponse);
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   143
    }
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   144
    
0e57c730bb18 Documentation and add alternative wp url and label + migrations
ymh <ymh.work@gmail.com>
parents: 34
diff changeset
   145
    
2
13f43f53d0ba first implementation
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
}