From: Eric Mahurin Date: 2007-09-03T15:51:07+09:00 Subject: Re: [QUIZ] Twisting a Rope (#137) ------=_Part_17535_22666276.1188802265486 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline On 8/31/07, Ruby Quiz wrote: > This week's task is to implement the Rope data structure as a Ruby class. My implementation is attached along with a modified test. I made a few changes to what was asked, but this also gave more flexibility. Here is what I did: * Just as the implementation in the paper referenced in this quiz, my implementation gives immutable ropes. #<< is non-destructive, so I had to change the test to do <<= instead of just <<. Also, I didn't implement #shift, because it must be destructive. The same functionality can be achieved with 2 calls to #slice (one could be #at if you only need to shift one element). There are very good reasons to make ropes immutable. I'd imagine almost every other implementation with modifiable ropes will fail when someone starts modifying a sub-rope that is shared. You'd really need a good COW (copy-on-write) scheme to allow both transparent sharing and modification. I didn't see that it was worth the effort/complexity/risk. I chose the simple functional programming approach (immutable objects). * I chose to automatically balance the ropes during concatenation (no normalize). I used the same tree rotations that are used with AVL trees. Another option could be to treat these as red-black trees which might save on some rotations. One reason I automatically balanced is that it simplifies the interface. The user of the API doesn't have to worry about when to normalize. A second reason is that every other rope operation is O(log(n)), so there probably isn't much benefit in making only concatenation O(1). * I don't allow ropes to directly use Strings. Instead, a StringRope is used as a proxy for a String. To use a String directly, I would have had to check the class, use respond_to, modify String to look like a rope, etc. Instead, I just went with the pure duck-typing approach and made multiple Rope-like classes that use different types of data. My basis for these is the class ArrayRope. There is no reason why a rope data-structure can't be used with any sequence of objects instead of just characters. ArrayRope takes an Array-like object. An rope built out of these is to Array as a conventional rope is to String. I also added an IORope class to lazily work with files. Using IORope you could make a text editor that didn't have to read the whole file in at once. There is no reason you can't mix and match any of these leaf rope classes (depth 0) within a rope tree. * #each iterates through elements (i.e. characters) in the rope. It annoys me that String#each (and IO#each for that matter) iterates over lines - it should be characters (not necessarily bytes). All of the Enumerable methods are accessible too. * I used #at instead of #index because #index is used for searching in String/Array. Array#at is an exact match. The main thing I didn't do was implement any regex stuff. I don't see how this is doable since all of the regex methods are completely tied to String (not duck-typed). You'd have to convert the whole rope to string to do anything (which defeats the purpose of the rope). ------=_Part_17535_22666276.1188802265486 Content-Type: application/x-ruby; name=quiz137.rb Content-Transfer-Encoding: base64 X-Attachment-Id: f_f64jpfn2 Content-Disposition: attachment; filename="quiz137.rb" CmNsYXNzIFJvcGUKICAgIGluY2x1ZGUgRW51bWVyYWJsZQogICAgIyBmb3JtIGEgYmluYXJ5IHRy ZWUgZnJvbSB0d28gcm9wZXMgKHBvc3NpYmx5IHN1Yi10cmVlcykKICAgIGRlZiBpbml0aWFsaXpl KGxlZnQscmlnaHQpCiAgICAgICAgQGxlZnQgPSBsZWZ0CiAgICAgICAgQHJpZ2h0ID0gcmlnaHQK ICAgICAgICBAbGxlbmd0aCA9IEBsZWZ0Lmxlbmd0aAogICAgICAgIEBsZW5ndGggPSBAbGxlbmd0 aCtAcmlnaHQubGVuZ3RoCiAgICAgICAgQGRlcHRoID0gW2xlZnQuZGVwdGgsIHJpZ2h0LmRlcHRo XS5tYXgrMQogICAgZW5kCiAgICAjIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHJvcGUKICAg IGRlZiBsZW5ndGgKICAgICAgICBAbGVuZ3RoCiAgICBlbmQKICAgICMgZGVwdGggb2YgdGhlIHRy ZWUgKHRvIGhlbHAga2VlcCB0aGUgdHJlZSBiYWxhbmNlZCkKICAgIGRlZiBkZXB0aAogICAgICAg IEBkZXB0aAogICAgZW5kCiAgICAjIGxlZnQgcm9wZSAobm90IG5lZWRlZCB3aGVuIGRlcHRoPT0w KQogICAgZGVmIGxlZnQKICAgICAgICBAbGVmdAogICAgZW5kCiAgICAjIHJpZ2h0IHJvcGUgKG5v dCBuZWVkZWQgd2hlbiBkZXB0aD09MCkKICAgIGRlZiByaWdodAogICAgICAgIEByaWdodAogICAg ZW5kCiAgICAjIGFwcGVuZGVkIHJvcGUgKG5vbi1tb2RpZnlpbmcpCiAgICBkZWYgPDwob3RoZXIp CiAgICAgICAgIyBiYWxhbmNlIGFzIGFuIEFWTCB0cmVlCiAgICAgICAgYmFsYW5jZSA9IG90aGVy LmRlcHRoLUBkZXB0aAogICAgICAgIGlmIGJhbGFuY2U+KzEKICAgICAgICAgICAgbGVmdCA9IG90 aGVyLmxlZnQKICAgICAgICAgICAgcmlnaHQgPSBvdGhlci5yaWdodAogICAgICAgICAgICBpZiBs ZWZ0LmRlcHRoPnJpZ2h0LmRlcHRoCiAgICAgICAgICAgICAgICAjIHJvdGF0ZSBvdGhlciB0byBy aWdodCBiZWZvcmUgcm90YXRpbmcgc2VsZitvdGhlciB0byBsZWZ0CiAgICAgICAgICAgICAgICAo c2VsZiA8PCBsZWZ0LmxlZnQpIDw8IChsZWZ0LnJpZ2h0IDw8IHJpZ2h0KQogICAgICAgICAgICBl bHNlCiAgICAgICAgICAgICAgICAjIHJvdGF0ZSBzZWxmK290aGVyIHRvIGxlZnQKICAgICAgICAg ICAgICAgIChzZWxmIDw8IGxlZnQpIDw8IHJpZ2h0CiAgICAgICAgICAgIGVuZAogICAgICAgIGVs c2lmIGJhbGFuY2U8LTEKICAgICAgICAgICAgaWYgQHJpZ2h0LmRlcHRoPkBsZWZ0LmRlcHRoCiAg ICAgICAgICAgICAgICAjIHJvdGF0ZSBzZWxmIHRvIGxlZnQgYmVmb3JlIHJvdGF0aW5nIHNlbGYr b3RoZXIgdG8gcmlnaHQKICAgICAgICAgICAgICAgIChAbGVmdCA8PCBAcmlnaHQubGVmdCkgPDwg KEByaWdodC5yaWdodCA8PCBvdGhlcikKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAg IyByb3RhdGUgc2VsZitvdGhlciB0byByaWdodAogICAgICAgICAgICAgICAgQGxlZnQgPDwgKEBy aWdodCA8PCBvdGhlcikKICAgICAgICAgICAgZW5kCiAgICAgICAgIyB1bmNvbW1lbnQgdGhpcyB0 byBhbGxvdyBzaG9ydCBzdHJpbmdzIHRvIGNvbmNhdCBmbGF0CiAgICAgICAgI2Vsc2lmIG90aGVy LmRlcHRoLnplcm8/CiAgICAgICAgIyAgICAjIGFsbG93IEByaWdodCBhbmQgb3RoZXIgdG8gYmUg bWVyZ2VkICh3aGVuIHRoZSBsZW5ndGggaXMgc2hvcnQpCiAgICAgICAgIyAgICBAbGVmdCA8PCAo QHJpZ2h0IDw8IG90aGVyKQogICAgICAgIGVsc2UKICAgICAgICAgICAgc2VsZi5jbGFzcy5uZXco c2VsZiwgb3RoZXIpCiAgICAgICAgZW5kCiAgICBlbmQKICAgICMgc2xpY2Ugb2YgdGhlIHJvcGUK ICAgIGRlZiBzbGljZShzdGFydCwgbGVuKQogICAgICAgIHJldHVybiBzZWxmIGlmIHN0YXJ0Lnpl cm8/IGFuZCBsZW49PUBsZW5ndGgKICAgICAgICByc3RhcnQgPSBzdGFydC1AbGxlbmd0aAogICAg ICAgIHJldHVybiBAcmlnaHQuc2xpY2UocnN0YXJ0LCBsZW4pIGlmIHJzdGFydD4wCiAgICAgICAg bGxlbiA9IEBsbGVuZ3RoLXN0YXJ0CiAgICAgICAgcmxlbiA9IGxlbi1sbGVuCiAgICAgICAgaWYg cmxlbj4wCiAgICAgICAgICAgIEBsZWZ0LnNsaWNlKHN0YXJ0LCBsbGVuKSA8PCBAcmlnaHQuc2xp Y2UoMCwgcmxlbikKICAgICAgICBlbHNlCiAgICAgICAgICAgIEBsZWZ0LnNsaWNlKHN0YXJ0LCBs ZW4pCiAgICAgICAgZW5kCiAgICBlbmQKICAgICMgZWxlbWVudCBhdCBhIGNlcnRhaW4gcG9zaXRp b24gaW4gdGhlIHJvcGUKICAgIGRlZiBhdChzdGFydCkKICAgICAgICByc3RhcnQgPSBzdGFydC1A bGxlbmd0aAogICAgICAgIGlmIHJzdGFydDwwCiAgICAgICAgICAgIEBsZWZ0LmF0KHN0YXJ0KQog ICAgICAgIGVsc2UKICAgICAgICAgICAgQHJpZ2h0LmF0KHJzdGFydCkKICAgICAgICBlbmQKICAg IGVuZAogICAgIyBpdGVyYXRlIHRocm91Z2ggdGhlIGVsZW1lbnRzIGluIHRoZSByb3BlCiAgICBk ZWYgZWFjaAogICAgICAgIEBsZWZ0LmVhY2ggeyB8eHwgeWllbGQgeCB9CiAgICAgICAgQHJpZ2h0 LmVhY2ggeyB8eHwgeWllbGQgeCB9CiAgICBlbmQKICAgICMgZmxhdHRlbiB0aGUgcm9wZSBpbnRv IGEgc3RyaW5nIChvcHRpb25hbGx5IHN0YXJ0aW5nIHdpdGggYSBwcmVmaXgpCiAgICBkZWYgdG9f cyhzPSIiKQogICAgICAgIEByaWdodC50b19zKEBsZWZ0LnRvX3MocykpCiAgICBlbmQKZW5kCgpF bXB0eVJvcGUgPSBPYmplY3QubmV3CmNsYXNzIDw8IEVtcHR5Um9wZQogICAgaW5jbHVkZSBFbnVt ZXJhYmxlCiAgICBkZWYgbGVuZ3RoCiAgICAgICAgMAogICAgZW5kCiAgICBkZWYgZGVwdGgKICAg ICAgICAwCiAgICBlbmQKICAgIGRlZiA8PChvdGhlcikKICAgICAgICBvdGhlcgogICAgZW5kCiAg ICBkZWYgPj4ob3RoZXIpCiAgICAgICAgb3RoZXIKICAgIGVuZAogICAgZGVmIHNsaWNlKHN0YXJ0 LCBsZW4pCiAgICAgICAgc2VsZgogICAgZW5kCiAgICBkZWYgZWFjaAogICAgZW5kCiAgICBkZWYg dG9fcwogICAgICAgICIiCiAgICBlbmQKZW5kCgpjbGFzcyBBcnJheVJvcGUKICAgIGluY2x1ZGUg RW51bWVyYWJsZQogICAgZGVmIHNlbGYubmV3KCphcmdzKQogICAgICAgIGlmIGFyZ3MuZW1wdHk/ CiAgICAgICAgICAgIEVtcHR5Um9wZQogICAgICAgIGVsc2UKICAgICAgICAgICAgc3VwZXIKICAg ICAgICBlbmQKICAgIGVuZAogICAgZGVmIGluaXRpYWxpemUoZGF0YSkKICAgICAgICBAZGF0YSA9 IGRhdGEKICAgIGVuZAogICAgZGVmIGxlbmd0aAogICAgICAgIEBkYXRhLmxlbmd0aAogICAgZW5k CiAgICBkZWYgZGVwdGgKICAgICAgICAwCiAgICBlbmQKICAgIGRlZiA8PChvdGhlcikKICAgICAg ICBiYWxhbmNlID0gb3RoZXIuZGVwdGgKICAgICAgICBpZiBiYWxhbmNlPjEKICAgICAgICAgICAg bGVmdCA9IG90aGVyLmxlZnQKICAgICAgICAgICAgcmlnaHQgPSBvdGhlci5yaWdodAogICAgICAg ICAgICBpZiBsZWZ0LmRlcHRoPnJpZ2h0LmRlcHRoCiAgICAgICAgICAgICAgICAjIHJvdGF0ZSBv dGhlciB0byByaWdodCBiZWZvcmUgcm90YXRpbmcgc2VsZitvdGhlciB0byBsZWZ0CiAgICAgICAg ICAgICAgICAoc2VsZiA8PCBsZWZ0LmxlZnQpIDw8IChsZWZ0LnJpZ2h0IDw8IHJpZ2h0KQogICAg ICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAjIHJvdGF0ZSBzZWxmK290aGVyIHRvIGxlZnQK ICAgICAgICAgICAgICAgIChzZWxmIDw8IGxlZnQpIDw8IHJpZ2h0CiAgICAgICAgICAgIGVuZAog ICAgICAgIGVsc2lmIG90aGVyLmxlbmd0aD09MAogICAgICAgICAgICAjIG5vdGhpbmcgdG8gYXBw ZW5kLCBzZWxmIHdpbGwgZG8KICAgICAgICAgICAgc2VsZgogICAgICAgIGVsc2UKICAgICAgICAg ICAgUm9wZS5uZXcoc2VsZiwgb3RoZXIpCiAgICAgICAgZW5kCiAgICBlbmQKICAgIGRlZiBzbGlj ZShzdGFydCwgbGVuKQogICAgICAgIHJldHVybiBzZWxmIGlmIHN0YXJ0Lnplcm8/IGFuZCBsZW49 PUBkYXRhLmxlbmd0aAogICAgICAgICMgZGVwZW5kIG9uIHJ1YnkncyBDT1cgbWVjaGFuaXNtIHRv IGp1c3QgcmVmZXJlbmNlIHRoZSBzbGljZSBkYXRhCiAgICAgICAgc2VsZi5jbGFzcy5uZXcoQGRh dGEuc2xpY2Uoc3RhcnQsIGxlbikpCiAgICBlbmQKICAgIGRlZiBhdChzdGFydCkKICAgICAgICBA ZGF0YS5hdChzdGFydCkKICAgIGVuZAogICAgZGVmIGVhY2gKICAgICAgICBAZGF0YS5lYWNoIHsg fHh8IHlpZWxkIHggfQogICAgZW5kCiAgICBkZWYgdG9fcyhzPSIiKQogICAgICAgIHMuY29uY2F0 KEBkYXRhLnRvX3MpCiAgICBlbmQKZW5kCgpjbGFzcyBTdHJpbmdSb3BlIDwgQXJyYXlSb3BlCiAg ICAjIHVuY29tbWVudCB0aGlzIHRvIGFsbG93IHNob3J0IHN0cmluZ3MgdG8gY29uY2F0IGZsYXQK ICAgICNTSE9SVCA9IDY0CiAgICAjZGVmIDw8KG90aGVyKQogICAgIyAgICBpZiBvdGhlci5sZW5n dGg9PTAKICAgICMgICAgICAgIHNlbGYKICAgICMgICAgZWxzaWYgQGRhdGEubGVuZ3RoK290aGVy Lmxlbmd0aDw9U0hPUlQKICAgICMgICAgICAgICMganVzdCBtZXJnZSB0aGUgc3RyaW5ncyBpZiB0 aGUgdG90YWwgbGVuZ3RoIGlzIHNob3J0CiAgICAjICAgICAgICBzZWxmLmNsYXNzLm5ldyhAZGF0 YStvdGhlci50b19zKQogICAgIyAgICBlbHNlCiAgICAjICAgICAgICBzdXBlcgogICAgIyAgICBl bmQKICAgICNlbmQKICAgIGRlZiBhdChzdGFydCkKICAgICAgICBAZGF0YVtzdGFydF0KICAgIGVu ZAogICAgZGVmIGVhY2gKICAgICAgICBAZGF0YS5lYWNoX2NoYXIgeyB8eHwgeWllbGQgeCB9CiAg ICBlbmQKZW5kCgpjbGFzcyBJT1JvcGUgPCBBcnJheVJvcGUKICAgIGluY2x1ZGUgRW51bWVyYWJs ZQogICAgZGVmIGluaXRpYWxpemUoaW8sIHN0YXJ0PTAsIGxlbmd0aD0oaW8uc2VlaygwLElPOjpT RUVLX0VORCk7aW8ucG9zLXN0YXJ0KSkKICAgICAgICBAaW8gPSBpbwogICAgICAgIEBzdGFydCA9 IHN0YXJ0CiAgICAgICAgQGxlbmd0aCA9IGxlbmd0aAogICAgZW5kCiAgICBkZWYgbGVuZ3RoCiAg ICAgICAgQGxlbmd0aAogICAgZW5kCiAgICBkZWYgc2xpY2Uoc3RhcnQsIGxlbikKICAgICAgICBy ZXR1cm4gc2VsZiBpZiBzdGFydC56ZXJvPyBhbmQgbGVuPT1AbGVuZ3RoCiAgICAgICAgIyBqdXN0 IHJlZmVyZW5jZSBhIGRpZmZlcmVudCBwYXJ0IG9mIHRoZSBJTwogICAgICAgIHNlbGYuY2xhc3Mu bmV3KEBpbywgQHN0YXJ0K3N0YXJ0LCBsZW4pCiAgICBlbmQKICAgIGRlZiBhdChzdGFydCkKICAg ICAgICBAaW8ucG9zID0gQHN0YXJ0K3N0YXJ0CiAgICAgICAgQGlvLmdldGMKICAgIGVuZAogICAg ZGVmIGVhY2gKICAgICAgICBAaW8ucG9zID0gQHN0YXJ0CiAgICAgICAgQGxlbmd0aC50aW1lcyB7 IHlpZWxkIEBpby5nZXRjIH0KICAgIGVuZAogICAgZGVmIHRvX3Mocz0iIikKICAgICAgICBAaW8u cG9zID0gQHN0YXJ0CiAgICAgICAgcy5jb25jYXQoQGlvLnJlYWQoQGxlbmd0aCkpCiAgICBlbmQK ZW5kCgoKcmVxdWlyZSAnYmVuY2htYXJrJwoKI1RoaXMgY29kZSBtYWtlIGEgU3RyaW5nL1JvcGUg b2YgIENIVU5LUyBjaHVua3Mgb2YgdGV4dAojZWFjaCBjaHVuayBpcyBTSVpFIGJ5dGVzIGxvbmcu ICBFYWNoIGNodW5rIHN0YXJ0cyB3aXRoCiNhbiA4IGJ5dGUgbnVtYmVyLiAgSW5pdGlhbGx5IHRo ZSBjaHVua3MgYXJlIHNodWZmbGVkIHRoZQojcXNvcnQgbWV0aG9kIHNvcnRzIHRoZW0gaW50byBh c2NlbmRpbmcgb3JkZXIuCiMKI3Bhc3MgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRvIHVzZSBhcyBh IHBhcmFtZXRlcgojcnVieSAtciByb3BlLnJiIHRoaXNfZmlsZSBSb3BlCgpwdXRzICdwcmVwYXJp bmcgZGF0YS4uLicKVGV4dENsYXNzID0gT2JqZWN0LmNvbnN0X2dldChBUkdWLnNoaWZ0IHx8IDpT dHJpbmcpCgpkZWYgcXNvcnQodGV4dCkKIHJldHVybiBUZXh0Q2xhc3MubmV3IGlmIHRleHQubGVu Z3RoID09IDAKIHBpdm90ID0gdGV4dC5zbGljZSgwLDgpLnRvX3MudG9faQogbGVzcyA9IFRleHRD bGFzcy5uZXcKIG1vcmUgPSBUZXh0Q2xhc3MubmV3CiBvZmZzZXQgPSA4K1NJWkUKIHdoaWxlIChv ZmZzZXQgPCB0ZXh0Lmxlbmd0aCkKICAgaSA9IHRleHQuc2xpY2Uob2Zmc2V0LDgpLnRvX3MudG9f aQogICBpZiBpIDwgcGl2b3QKICAgICAgIGxlc3MgPDw9IHRleHQuc2xpY2Uob2Zmc2V0LDgrU0la RSkKICAgZWxzZQogICAgICAgbW9yZSA8PD0gdGV4dC5zbGljZShvZmZzZXQsOCtTSVpFKQogICBl bmQKICAgb2Zmc2V0ID0gb2Zmc2V0ICsgOCtTSVpFCiBlbmQKIHByaW50ICIqIgogcmV0dXJuIHFz b3J0KGxlc3MpIDw8IHRleHQuc2xpY2UoMCw4K1NJWkUpIDw8IHFzb3J0KG1vcmUpCmVuZAoKc3Jh bmQoMTIzNDU2Nzg5KQpTSVpFICA9IDUxMiAqIDEwMjQKQ0hVTktTID0gMTI4CkNIQVJTID0gJXdb UiBPIFAgRV0KYnVsa19zdHJpbmcgPSBBcnJheS5uZXcoU0laRSkgeyBDSEFSU1tyYW5kKDQpXSB9 LmpvaW4KYnVsa190ZXh0ID0gVGV4dENsYXNzLm5ldyhidWxrX3N0cmluZykKYnVpbGQgPSBbXQpk YXRhID0gbmlsCjgudGltZXMgewpwdXRzICdCdWlsZGluZyBUZXh0Li4uJwpHQy5zdGFydApidWls ZCA8PCBCZW5jaG1hcmsubWVhc3VyZSBkbwogZGF0YSA9IFRleHRDbGFzcy5uZXcKICgwLi5DSFVO S1MpLnNvcnRfYnkgeyByYW5kIH0uZWFjaCBkbyB8bnwKICAgZGF0YSA8PD0gVGV4dENsYXNzLm5l dyhzcHJpbnRmKCIlMDhpIixuKSkgPDwgYnVsa190ZXh0CiBlbmQKIGRhdGEubm9ybWFsaXplICBp ZiBkYXRhLnJlc3BvbmRfdG8/IDpub3JtYWxpemUKZW5kCn0KYnVpbGQgPSBidWlsZC5pbmplY3Qg eyB8bWluLGN1cnwgY3VyLnRvdGFsPG1pbi50b3RhbCA/IGN1ciA6IG1pbiB9CgoKIyBzZWxmLWNo ZWNrIHRoYXQgdGhlIGluZGljZXMgYWRkIHVwCnN1bSA9IDAKMC5zdGVwKGRhdGEubGVuZ3RoLTEs IDgrU0laRSkgeyB8b2Zmc2V0fAogICAgc3VtICs9IGRhdGEuc2xpY2Uob2Zmc2V0LDgpLnRvX3Mu dG9faQogICAgYnVsa19kYXRhID0gZGF0YS5zbGljZShvZmZzZXQrOCxTSVpFKS50b19zCiAgICBy YWlzZSgiI3tidWxrX2RhdGFbMCwxMF19Li4uLiAhPSAje2J1bGtfc3RyaW5nWzAsMTBdfS4uLi4i KSBpZiBidWxrX2RhdGEhPWJ1bGtfc3RyaW5nCn0KZXhwZWN0ZWRfc3VtID0gKENIVU5LUyooQ0hV TktTKzEpKS8yCnJhaXNlKCIje3N1bX0hPSN7ZXhwZWN0ZWRfc3VtfSIpIGlmIHN1bSE9ZXhwZWN0 ZWRfc3VtCgpzb3J0ID0gW10Kc29ydGVkX2RhdGEgPSBuaWwKOC50aW1lcyB7CkdDLnN0YXJ0CnNv cnQgPDwgQmVuY2htYXJrLm1lYXN1cmUgZG8KIHB1dHMgIlNvcnRpbmcgVGV4dC4uLiIKIHNvcnRl ZF9kYXRhID0gcXNvcnQoZGF0YSkKIHB1dHMiXG4iCmVuZAp9CnNvcnQgPSBzb3J0LmluamVjdCB7 IHxtaW4sY3VyfCBjdXIudG90YWw8bWluLnRvdGFsID8gY3VyIDogbWluIH0KCnB1dHMgIkJ1aWxk OiAje2J1aWxkfVNvcnQ6ICN7c29ydH0iCgojIHNlbGYtY2hlY2sgdGhhdCB0aGUgaW5kaWNlcyBh cmUgc29ydGVkCmkgPSAwCjAuc3RlcChzb3J0ZWRfZGF0YS5sZW5ndGgtMSwgOCtTSVpFKSB7IHxv ZmZzZXR8CiAgICBkYXRhaSA9IHNvcnRlZF9kYXRhLnNsaWNlKG9mZnNldCw4KS50b19zCiAgICBy YWlzZSgiI3tkYXRhaX0hPSN7aX0iKSBpZiBkYXRhaS50b19pIT1pCiAgICBidWxrX2RhdGEgPSBz b3J0ZWRfZGF0YS5zbGljZShvZmZzZXQrOCxTSVpFKS50b19zCiAgICByYWlzZSgiI3tidWxrX2Rh dGFbMCwxMF19Li4uLiAhPSAje2J1bGtfc3RyaW5nWzAsMTBdfS4uLi4iKSBpZiBidWxrX2RhdGEh PWJ1bGtfc3RyaW5nCiAgICBpICs9IDEKfQoKCg== ------=_Part_17535_22666276.1188802265486--