Herb Derby | 2e84591 | 2019-01-31 18:46:36 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2018 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include <vector> |
| 9 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 10 | #include "bench/Benchmark.h" |
| 11 | #include "include/core/SkFont.h" |
| 12 | #include "include/core/SkTypeface.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 13 | #include "src/core/SkUtils.h" |
| 14 | #include "src/utils/SkUTF.h" |
Herb Derby | 2e84591 | 2019-01-31 18:46:36 -0500 | [diff] [blame] | 15 | |
| 16 | // From Project Guttenberg. This is UTF-8 text. |
| 17 | static const char* atext[] = { |
| 18 | "Call me Ishmael. Some years ago--never mind how", |
| 19 | "long precisely --having little or no money in my purse, and nothing particular", |
| 20 | "to interest me on shore, I thought I would sail about a little and see the", |
| 21 | "watery part of the world. It is a way I have of driving off the spleen, and", |
| 22 | "regulating the circulation. Whenever I find myself growing grim about the", |
| 23 | "mouth; whenever it is a damp, drizzly November in my soul; whenever I find", |
| 24 | "myself involuntarily pausing before coffin warehouses, and bringing up the", |
| 25 | "rear of every funeral I meet; and especially whenever my hypos get such an", |
| 26 | "upper hand of me, that it requires a strong moral principle to prevent me", |
| 27 | "from deliberately stepping into the street, and methodically knocking", |
| 28 | "people's hats off--then, I account it high time to get to sea as soon as I can.", |
| 29 | "", |
| 30 | "This is my substitute for pistol and ball. With a philosophical flourish", |
| 31 | "Cato throws himself upon his sword; I quietly take to the ship. There is", |
| 32 | "nothing surprising in this. If they but knew it, almost all men in their", |
| 33 | "degree, some time or other, cherish very nearly the same feelings towards the", |
| 34 | "ocean with me. There now is your insular city of the Manhattoes, belted round", |
| 35 | "by wharves as Indian isles by coral reefs--commerce surrounds it with her surf.", |
| 36 | "", |
| 37 | "Right and left, the streets take you waterward. Its extreme down-town is", |
| 38 | "the battery, where that noble mole is washed by waves, and cooled by", |
| 39 | "breezes, which a few hours previous were out of sight of land. Look at the", |
| 40 | "crowds of water-gazers there. Circumambulate the city of a dreamy Sabbath", |
| 41 | "afternoon. Go from Corlears Hook to Coenties Slip, and from thence, by", |
| 42 | "Whitehall northward. What do you see?--Posted like silent sentinels all", |
| 43 | "around the town, stand thousands upon thousands of mortal men fixed in ocean", |
| 44 | "reveries. Some leaning against the spiles; some seated upon the pier-heads;", |
| 45 | "some looking over the bulwarks glasses!", |
| 46 | "of ships from China; some high aloft in the rigging, as if striving to get a", |
| 47 | "still better seaward peep. But these are all landsmen; of week days pent up", |
| 48 | "in lath and plaster--tied to counters, nailed to benches, clinched to desks.", |
| 49 | "How then is this? Are the green fields gone? What do they here? But look!", |
| 50 | "here come more crowds, pacing straight for the water, and seemingly bound for", |
| 51 | "a dive. Strange! Nothing will content them but the extremest limit of the", |
| 52 | "land; loitering under the shady lee of yonder warehouses will not suffice.", |
| 53 | "No. They must get just as nigh the water as they possibly can without falling", |
| 54 | "in. And there they stand--miles of them--leagues. Inlanders all, they come", |
| 55 | "from lanes and alleys, streets and avenues, --north, east, south, and west.", |
| 56 | "Yet here they all unite. Tell me, does the magnetic virtue of the needles of", |
| 57 | "the compasses of all those ships attract them thither? Once more. Say, you", |
| 58 | "are in the country; in some high land of lakes. Take almost any path you", |
| 59 | "please, and ten to one it carries you down in a dale, and leaves you there", |
| 60 | "by a pool in the stream. There is magic in it. Let the most absent-minded", |
| 61 | "of men be plunged in his deepest reveries--stand that man on his legs, set his", |
| 62 | "feet a-going, and he will infallibly lead you to water, if water there be in", |
| 63 | "all that region. Should you ever be athirst in the great American desert,", |
| 64 | "try this experiment, if your caravan happen to be supplied with a metaphysical", |
| 65 | "professor. Yes, as every one knows, meditation and water are wedded for ever.", |
| 66 | "", |
| 67 | "But here is an artist. He desires to paint you the dreamiest, shadiest,", |
| 68 | "quietest, most enchanting bit of romantic landscape in all the valley of the", |
| 69 | "Saco. What is the chief element he employs? There stand his trees, each with", |
| 70 | "a hollow trunk, as if a hermit and a crucifix were within; and here sleeps", |
| 71 | "his meadow, and there sleep his cattle; and up from yonder cottage goes a", |
| 72 | "sleepy smoke. Deep into distant woodlands winds a mazy way, reaching to", |
| 73 | "overlapping spurs of mountains bathed in their hill-side blue. But though", |
| 74 | "the picture lies thus tranced, and though this pine-tree shakes down its sighs", |
| 75 | "like leaves upon this shepherd's head, yet all were vain, unless the", |
| 76 | "shepherd's eye were fixed upon the magic stream before him. Go visit the", |
| 77 | "Prairies in June,", |
| 78 | "", |
| 79 | "when for scores on scores of miles you wade knee-deep among Tiger-lilies--what", |
| 80 | "is the one charm wanting? --Water --there is not a drop of water there! Were", |
| 81 | "Niagara but a cataract of sand, would you travel your thousand miles to see", |
| 82 | "it? Why did the poor poet of Tennessee, upon suddenly receiving two handfuls", |
| 83 | "of silver, deliberate whether to buy him a coat, which he sadly needed, or", |
| 84 | "invest his money in a pedestrian trip to Rockaway Beach? Why is almost every", |
| 85 | "robust healthy boy with a robust healthy soul in him, at some time or other", |
| 86 | "crazy to go to sea? Why upon your first voyage as a passenger, did you", |
| 87 | "yourself feel such a mystical vibration, when first told that you and your", |
| 88 | "ship were now out of sight of land? Why did the old Persians hold the sea", |
| 89 | "holy? Why did the Greeks give it a separate deity, and own brother of Jove?", |
| 90 | "Surely all this is not without meaning. And still deeper the meaning of that", |
| 91 | "story of Narcissus, who because he could not grasp the tormenting, mild image", |
| 92 | "he saw in the fountain, plunged into it and was drowned. But that same", |
| 93 | "image, we ourselves see in all rivers and oceans. It is the image of the", |
| 94 | "ungraspable phantom of life; and this is the key to it all. Now, when I say", |
| 95 | "that I am in the habit of going to sea whenever I begin to grow hazy about the", |
| 96 | "eyes, and begin to be over conscious of my lungs, I do not mean to have it", |
| 97 | "inferred that I ever go to sea as a passenger. For to go as a passenger you", |
| 98 | "must needs have a purse, and a purse is but a rag unless you have something", |
| 99 | "in it. Besides, passengers get sea-sick --grow quarrelsome --don't sleep of", |
| 100 | "nights --do not enjoy themselves much, as a general thing; --no, I never go as a", |
| 101 | "passenger; nor, though I am something of a salt, do I ever go to sea as a", |
| 102 | "Commodore, or a Captain, or a Cook. I abandon the glory and distinction of", |
| 103 | "such offices to those who like them. For my part, I abominate all honorable", |
| 104 | "respectable toils, trials, and tribulations of every kind whatsoever. It is", |
| 105 | "quite as much as I can do to take care of myself, without taking care of", |
| 106 | "ships, barques, brigs, schooners, and what not. And as for going as cook, --", |
| 107 | "though I confess there is considerable glory in that, a cook being a sort of", |
| 108 | "officer on ship-board --yet, somehow, I never fancied broiling fowls; --though", |
| 109 | "once broiled, judiciously buttered, and judgmatically salted and peppered,", |
| 110 | "there is no one who will", |
| 111 | "", |
| 112 | "speak more respectfully, not to say reverentially, of a broiled fowl than I", |
| 113 | "will. It is out of the idolatrous dotings of the old Egyptians upon broiled", |
| 114 | "ibis and roasted river horse, that you see the mummies of those creatures in", |
| 115 | "their huge bake-houses the pyramids. No, when I go to sea, I go as a simple", |
| 116 | "sailor, right before the mast, plumb down into the forecastle, aloft there", |
| 117 | "to the royal mast-head. True, they rather order me about some, and make me", |
| 118 | "jump from spar to spar, like a grasshopper in a May meadow. And at first,", |
| 119 | "this sort of thing is unpleasant enough. It touches one's sense of honor,", |
| 120 | "particularly if you come of an old established family in the land, the van", |
| 121 | "Rensselaers, or Randolphs, or Hardicanutes. And more than all, if just", |
| 122 | "previous to putting your hand into the tar-pot, you have been lording it as a", |
| 123 | "country schoolmaster, making the tallest boys stand in awe of you. The", |
| 124 | "transition is a keen one, I assure you, from the schoolmaster to a sailor,", |
| 125 | "and requires a strong decoction of Seneca and the Stoics to enable you to grin", |
| 126 | "and bear it. But even this wears off in time. What of it, if some old hunks", |
| 127 | "of a sea-captain orders me to get a broom and sweep down the decks? What does", |
| 128 | "that indignity amount to, weighed, I mean, in the scales of the New", |
| 129 | "Testament? Do you think the archangel Gabriel thinks anything the less of me,", |
| 130 | "because I promptly and respectfully obey that old hunks in that particular", |
| 131 | "instance? Who aint a slave? Tell me that. Well, then, however the old", |
| 132 | "sea-captains may order me about--however they may thump and punch me about, I", |
| 133 | "have the satisfaction of knowing that it is all right; that everybody else", |
| 134 | "is one way or other served in much the same way -- either in a physical or", |
| 135 | "metaphysical point of view, that is; and so the universal thump is passed", |
| 136 | "round, and all hands should rub each other's shoulder-blades, and be", |
| 137 | "content. Again, I always go to sea as a sailor, because they make a point of", |
| 138 | "paying me for my trouble, whereas they never pay passengers a single penny", |
| 139 | "that I ever heard of. On the contrary, passengers themselves must pay. And", |
| 140 | "there is all the difference in the world between paying and being paid. The", |
| 141 | "act of paying is perhaps the most uncomfortable infliction that the two", |
| 142 | "orchard thieves entailed upon us." |
| 143 | }; |
| 144 | |
| 145 | static const char* ctext[] = { |
| 146 | "第一回", |
| 147 | "胡秀才告狀鳴冤 施賢臣得夢訪案", |
| 148 | "", |
| 149 | " 話說江都縣有一秀才,姓胡,名登舉。他的父母為人所殺,頭顱不見。胡登舉合家", |
| 150 | "嚇得膽裂魂飛,慌忙出門,去稟縣主。", |
| 151 | "", |
| 152 | " 跑到縣衙,正遇升堂,就進去喊冤。走至堂上,打了一躬,手舉呈詞,口稱:「父", |
| 153 | "師在上,門生禍從天降。叩稟老父師,即賜嚴拿。」說著,將呈詞遞上。書吏接過,鋪", |
| 154 | "在公案。施公靜心細閱。上寫:具呈生員胡登舉,祖居江都縣。生父曾作翰林,告老家", |
| 155 | "居,廣行善事,憐恤窮苦,並無苛刻待人之事。不意於某日夜間,生父母閉戶安眠。至", |
| 156 | "天曉,生往請安,父母俱不言語。生情急,踢開門戶,見父母屍身俱在牀上,兩個人頭", |
| 157 | ",並沒蹤影。生忝居學校,父母如此死法,何以身列校庠對雙親而無愧乎?為此具呈,", |
| 158 | "嚎叩老父師大人恩准,速賜拿獲兇手,庶生冤仇得雪。感戴無既。沾仁。上呈。", |
| 159 | "", |
| 160 | " 施公看罷,不由點頭,暗暗吃驚,想道:「夤夜入院,非奸即盜。胡翰林夫婦年老", |
| 161 | "被殺,而不竊去財物,且將人頭拿去,其中情由,顯係仇謀。此宗無題文章,令人如何", |
| 162 | "做法?」為難良久,說道:「即委捕廳四老爺,前去驗屍。你只管入殮,自有頭緒結斷", |
| 163 | "。」胡秀才一聽,只得含淚下堂,出衙回家,伺候驗屍。", |
| 164 | "", |
| 165 | " 且說施公吩咐速去知會四衙,往胡家驗屍呈報,把呈詞收入袖內,吩咐退堂。進內", |
| 166 | "書房坐下,長隨送茶畢,用過了飯,把呈詞取出,鋪在案上翻閱。低頭細想,此案難結", |
| 167 | "。欠身伸手,在書架上拿了古書一部,係《拍案稱奇》,放在桌上要看;對證此案,即", |
| 168 | "日好斷這沒頭之事。將《拍案稱奇》,自頭至尾看完,又取了一部,係海瑞參拿嚴嵩的", |
| 169 | "故事。不覺困倦,放下書本,伏於書案之上,朦朧打睡。夢中看見外邊牆頭之下,有群", |
| 170 | "黃雀兒九隻,點頭搖尾,唧哩喳啦,不住亂叫。施公一見,心中甚驚。又聽見地上哼哼", |
| 171 | "唧唧的豬叫;原來是油光兒的七個小豬兒,望著賢臣亂叫。施公夢中稱奇,方要去細看", |
| 172 | ",那九隻黃雀兒,一齊飛下牆來,與地下七個小豬兒,點頭亂噪。那七個小豬兒,站起", |
| 173 | "身來,望黃雀拱抓,口內哼哼亂叫。雀噪豬叫,偶然起了一陣怪風,把豬雀都裹了去了", |
| 174 | "。施公夢中一聲驚覺,大叫說:「奇怪的事!」施安在旁邊站立,見主人如此驚叫,不", |
| 175 | "知何故,連忙叫:「老爺醒來!醒來!」施公聽言,抬頭睜眼,沉吟多時。想夢中之事", |
| 176 | ",說:「奇哉!怪哉!」就問施安這天有多時了。施安答道:「日色西沉了。」施公點", |
| 177 | "頭,又問:「方才你可見些什麼東西沒有?」施安說:「並沒見什麼東西,倒有一陣風", |
| 178 | "刮過牆去。」施公聞言,心中細想,這九隻黃雀、七個小豬奇怪,想來內有曲情。將書", |
| 179 | "擱在架上,前思後想,一夜未睡。直到天明,淨面整衣,吩咐傳梆升堂。坐下,抽籤叫", |
| 180 | "快頭英公然、張子仁上來。二人走至堂上,跪下叩頭。施公就將昨日夢見九隻黃雀、七", |
| 181 | "個小豬為題出簽差人,說:「限你二人五日之期,將九黃、七豬拿來,如若遲延,重責", |
| 182 | "不饒。」將簽遞於二人。二人跪趴半步,口稱:「老爺容稟:小的們請個示來。", |
| 183 | "", |
| 184 | " 這九黃、七豬,是兩個人名,還是兩個物名,現在何處?求老爺吩咐明白,小的們", |
| 185 | "好去訪拿。」言罷叩頭。施公一聽,說道:「無用奴才,連個九黃、七豬都不知道,還", |
| 186 | "在本縣應役麼?分明偷閒躲懶,安心抗差玩法。」吩咐:「給我拉下去打!」兩邊發喊", |
| 187 | "按倒,每人打了十五板。二人跪下叩頭,復又討示,叫聲:「老爺,究竟吩咐明白,待", |
| 188 | "小的們好去拿人。」施公聞言,心中不由大怒,說:「好大膽的奴才!本縣深知你二人", |
| 189 | "久慣應役,極會搪塞,如敢再行囉唣,定加重責!」二人聞言,萬分無奈,站起退下去", |
| 190 | ",訪拿九黃、七豬而去。施公也隨退堂。", |
| 191 | "", |
| 192 | " 施公一連五日,假裝有恙,並未升堂。到了第六日,一早吩咐點鼓升堂,坐下。衙", |
| 193 | "役人等伺候。只見一人走至公堂案下,手捧呈詞,口稱:「父師,門生胡登舉父母被殺", |
| 194 | "之冤,求父師明鑒。倘遲久不獲,兇犯走脫難捉。且生員讀書一場,豈不有愧?如門生", |
| 195 | "另去投呈伸冤,老父台那時休怨!」言罷一躬,將呈遞上。施公帶笑道:「賢契不必急", |
| 196 | "躁。本縣已經差人明捕暗訪,專拿形跡可疑之人,審得自然替你申冤。」胡登舉無奈,", |
| 197 | "說道:「父台!速替門生伸冤,感恩不盡!」施公說:「賢契請回,催呈留下。」胡登", |
| 198 | "舉打躬下堂,出衙回家。且說施公為難多會,方要提胡宅管家的審問,只見公差英公然", |
| 199 | "、張子仁上堂,跪下回稟:「小的二人,並訪不著九黃、七豬,求老爺寬限。」", |
| 200 | "", |
| 201 | " 施公聞言,激惱成怒,喝叫左右拉下,每人打十五大板。不容分說,只打的哀求不", |
| 202 | "止,鮮血直流。打完提褲,戰戰兢兢,跪在地下,口尊:「老爺,叩討明示,以便好去", |
| 203 | "捉人。」施公聞言無奈,硬著心腸說道:「再寬你們三日限期,如其再不捉拿兇犯,定", |
| 204 | "行處死!」二差聞言,篩糠打戰,只是磕頭,如雞食碎米一般。施公又說:「你們不必", |
| 205 | "多說,快快去捕要緊。」施公想二役兩次受刑,亦覺心中不忍,退堂進內。可憐二人還", |
| 206 | "在下面叩頭,大叫:「老爺,可憐小的們性命罷!」言畢,又是咚咚的叩頭。縣堂上未", |
| 207 | "散的三班六房之人,見二人這樣,個個兔死狐悲,歎惜不止,一齊說:「罷呀!起來罷", |
| 208 | "!老爺進去了,還求那個?」二人聞言,抬頭不看見老爺,忍氣站起,腿帶棒傷,身形", |
| 209 | "晃亂。旁邊上來四個人,用手挽架下堂。"}; |
| 210 | |
| 211 | |
| 212 | class UtfToGlyph : public Benchmark { |
| 213 | public: |
| 214 | UtfToGlyph(SkTextEncoding encoding, const char* (*text), int lineCount, const char* name) |
| 215 | : fEncoding{encoding} |
| 216 | , fText{text} |
| 217 | , fLineCount{lineCount} |
| 218 | , fName{name} { } |
| 219 | |
| 220 | protected: |
| 221 | const char* onGetName() override { |
| 222 | return fName; |
| 223 | } |
| 224 | |
| 225 | bool isSuitableFor(Backend backend) override { |
| 226 | return backend == kNonRendering_Backend; |
| 227 | } |
| 228 | |
| 229 | void onDelayedSetup() override { |
| 230 | int maxGlyphs = 0; |
| 231 | for (int i = 0; i < fLineCount; i++) { |
| 232 | fLines.emplace_back(this->convertLine(i)); |
| 233 | maxGlyphs = std::max(maxGlyphs, fLines.back()->glyphCount); |
| 234 | } |
| 235 | fGlyphIds.insert(fGlyphIds.begin(), maxGlyphs, 0); |
| 236 | fTypeface = SkTypeface::MakeFromName("monospace", SkFontStyle()); |
| 237 | } |
| 238 | |
| 239 | void onDraw(int loops, SkCanvas* canvas) override { |
Mike Reed | 64670cb | 2019-04-16 11:37:38 -0700 | [diff] [blame] | 240 | SkFont font(fTypeface); |
Herb Derby | 2e84591 | 2019-01-31 18:46:36 -0500 | [diff] [blame] | 241 | // Do more loops to reduce variance. |
| 242 | for (int i = 0; i < loops * 3; ++i) { |
| 243 | for (auto& line : fLines) { |
Mike Reed | 64670cb | 2019-04-16 11:37:38 -0700 | [diff] [blame] | 244 | font.textToGlyphs(line->utf.data(), line->utf.size(), fEncoding, |
| 245 | fGlyphIds.data(), line->glyphCount); |
Herb Derby | 2e84591 | 2019-01-31 18:46:36 -0500 | [diff] [blame] | 246 | } |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | private: |
| 251 | struct Line { |
| 252 | int glyphCount = 0; |
| 253 | std::vector<char> utf; |
| 254 | }; |
| 255 | |
| 256 | std::unique_ptr<Line> convertLine(int lineIndex) { |
Mike Klein | f46d5ca | 2019-12-11 10:45:01 -0500 | [diff] [blame] | 257 | std::unique_ptr<Line> result = std::make_unique<Line>(); |
Herb Derby | 2e84591 | 2019-01-31 18:46:36 -0500 | [diff] [blame] | 258 | |
| 259 | const char* cursor = fText[lineIndex]; |
| 260 | size_t len = strlen(cursor); |
| 261 | const char* end = cursor + len; |
| 262 | result->glyphCount = SkUTF::CountUTF8(cursor, len); |
| 263 | std::vector<char>& bytes = result->utf; |
| 264 | while (cursor < end) { |
| 265 | SkUnichar u = SkUTF::NextUTF8(&cursor, end); |
| 266 | |
| 267 | switch (fEncoding) { |
| 268 | case SkTextEncoding::kUTF8: { |
| 269 | char buffer[SkUTF::kMaxBytesInUTF8Sequence]; |
| 270 | size_t count = SkUTF::ToUTF8(u, buffer); |
| 271 | result->utf.insert(bytes.end(), buffer, buffer + count); |
| 272 | break; |
| 273 | } |
| 274 | case SkTextEncoding::kUTF16: { |
| 275 | uint16_t buffer[2]; |
| 276 | size_t count = SkUTF::ToUTF16(u, buffer); |
| 277 | result->utf.insert(bytes.end(), (char *)buffer, (char *)buffer + count * 2); |
| 278 | break; |
| 279 | } |
| 280 | case SkTextEncoding::kUTF32: { |
| 281 | result->utf.insert(bytes.end(), (char*) &u, (char*) &u + 4); |
| 282 | break; |
| 283 | } |
| 284 | default: |
| 285 | SK_ABORT("Bad encoding"); |
| 286 | } |
| 287 | } |
| 288 | |
| 289 | return result; |
| 290 | } |
| 291 | |
| 292 | SkTextEncoding fEncoding; |
| 293 | std::vector<std::unique_ptr<Line>> fLines; |
| 294 | std::vector<SkGlyphID> fGlyphIds; |
| 295 | sk_sp<SkTypeface> fTypeface; |
Mike Klein | b78729a | 2019-12-02 12:43:11 -0600 | [diff] [blame] | 296 | const char** fText; |
Herb Derby | 2e84591 | 2019-01-31 18:46:36 -0500 | [diff] [blame] | 297 | int fLineCount; |
| 298 | const char* fName; |
| 299 | }; |
| 300 | |
| 301 | DEF_BENCH(return new UtfToGlyph(SkTextEncoding::kUTF32, ctext, SK_ARRAY_COUNT(ctext), |
| 302 | "SkTypefaceUTF32ToGlyphCN");) |
| 303 | DEF_BENCH(return new UtfToGlyph(SkTextEncoding::kUTF16, ctext, SK_ARRAY_COUNT(ctext), |
| 304 | "SkTypefaceUTF16ToGlyphCN");) |
| 305 | DEF_BENCH(return new UtfToGlyph(SkTextEncoding::kUTF8, ctext, SK_ARRAY_COUNT(ctext), |
| 306 | "SkTypefaceUTF8ToGlyphCN");) |
| 307 | |
| 308 | |
| 309 | DEF_BENCH(return new UtfToGlyph(SkTextEncoding::kUTF32, atext, SK_ARRAY_COUNT(atext), |
| 310 | "SkTypefaceUTF32ToGlyphAscii");) |
| 311 | DEF_BENCH(return new UtfToGlyph(SkTextEncoding::kUTF16, atext, SK_ARRAY_COUNT(atext), |
| 312 | "SkTypefaceUTF16ToGlyphAscii");) |
| 313 | DEF_BENCH(return new UtfToGlyph(SkTextEncoding::kUTF8, atext, SK_ARRAY_COUNT(atext), |
| 314 | "SkTypefaceUTF8ToGlyphAscii");) |
| 315 | |
| 316 | |
| 317 | |