AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 5907 |
r3wp | 58701 |
total: | 64608 |
results window for this page: [start: 33201 end: 33300]
world-name: r3wp
Group: I'm new ... Ask any question, and a helpful person will try to answer. [web-public] | ||
jonty: 16-Jun-2010 | hmm, doesn't understand clipboard. Is it a windows only thing? | |
jonty: 16-Jun-2010 | (Update fails as well, I know there is a newer v2) | |
Maxim: 16-Jun-2010 | might be that its not working on OSX, there are quite a few OSX REBOLers here, one will surely pop up and confirm/infirm | |
Gregg: 16-Jun-2010 | Welcome Jonathan! The console is your friend, but you're not the first to overwrite a system word and have to start a new session. REBOL has a few gotchas. With great power and all that. >> d: now/weekday == 3 >> pick system/locale/days d == "Wednesday" >> system/locale/days/:d == "Wednesday" >> day-name: func [date [date!]] [pick system/locale/days date/weekday] >> day-name now == "Wednesday" | |
Henrik: 16-Jun-2010 | That depends if you have access to libraries that already do this. REBOL can't do this directly, but it may be possible through a DLL. | |
Sunanda: 16-Jun-2010 | REBOL does not currently run _on_ any phones (that I know of) though this blog post offers some hope: http://www.rebol.com/cgi-bin/blog.r?view=0274 If you want to connect _to_ a phone from a REBOL-supported platform (Win, Lin, MAC, etc) then, as Henrik says, the crucial issue is the API to access the phone's functions. REBOL can probable connect to that API. But without more details, we'd be guessing. | |
Henrik: 16-Jun-2010 | I'd suggest that if you want to try REBOL, you need to figure out the basics first to figure out why we use it. REBOL is not a very popular language, but the followers are pretty loyal. | |
Toma: 16-Jun-2010 | oh thank you a lot, i think there i finde some answers | |
DKnell: 20-Jun-2010 | Just thought I'd wave hello in here. I've been following the rebol project a while and decided to take the plunge. I have both rebol2 and 3 downloaded, I assume viewtop is only enable for rebol2 at the moment and rebol3 is cli only? | |
Henrik: 20-Jun-2010 | welcome! and yes, correct, r3 doesn't have a desktop and won't get one. it will be replaced with ReBrowse, a browser-like launcher environment. | |
Henrik: 20-Jun-2010 | no ETA on rebrowse. it will be quite a while before R3 is done. if you want a "complete" experience, you can focus on R2. R3 is the cutting edge, where development happens, but it's incomplete. | |
DKnell: 21-Jun-2010 | I guess what I'm trying to avoid is spending a lot of time learning something in r2 which is obsolete/redundant or majorly different in r3. I suppose I could try running the various r2 demos and one liners under r3 and learn for myself the syntax differences. | |
DKnell: 21-Jun-2010 | Yes that makes sense. It was the words i read that "r3 was a complete rewrite of r2" that made me question whether it was worth learning all parts of r2 | |
DKnell: 21-Jun-2010 | great, r2 it is then. I've been passively watching the rebol project for a while now, years in fact. I'm now keen to 'at last' throw time at it , learn it all and start programming in it | |
DKnell: 21-Jun-2010 | ok, simple r2 problem i'm having. the cli window is closing as soon as the script ends when i run the simple demos via the viewtop. Any way to force the cli window to remain open - besides adding a "press any key" context to end of each script.. I'm using xp at the moment I swear the window use to remain open - but maybe I am confused with my linux rebol experiences.. | |
Henrik: 21-Jun-2010 | there may be a quit command in the script, so the script will close the console no matter what. | |
DKnell: 21-Jun-2010 | no there is no quit command. actually i've run a few scripts which have halt at the end, and that keeps the output window open | |
DKnell: 21-Jun-2010 | Thinking about this, it's only natural for any output console window to close after script execution. For running the demos via viewtop though, it would be nice to either have the script wait at the end, ask for user entry, or maybe have a permanent viewtop console window. | |
Henrik: 21-Jun-2010 | ok, that script needs a HALT at the end. | |
Henrik: 21-Jun-2010 | When you launch them from the viewtop, a separate process is created. | |
DKnell: 21-Jun-2010 | Well I'm just a typical new user trying out the demos from viewtop. I know there's a few ways to execute code | |
AdrianS: 21-Jun-2010 | David, you might also want to look at the r2-forward script by BrianH - it's intended to retrofit a good amount of the newer R3 functionality into R2. You can dowload that using R3 chat. | |
BrianH: 21-Jun-2010 | Most of R2/Forward was added to R2 itself with the 2.7.7 release. The rest was added to 2.7.8 (release pending). There are some limits as to what R3 functionality can be retrofitted into R2, but you'd be surprised. Also, look at the source - it's also meant to serve as documentation about differences between R3 and R2, although it can be a bit on the advanced side here and there. | |
AdrianS: 21-Jun-2010 | Brian, what's the intent wrt delect? With Carl's most recent wiki page describing commands, it seems that a fair amount of delect's parsing power (optional, out of order args) won't be available using these - is delect going to remain? | |
BrianH: 21-Jun-2010 | It's unknown at this point whether DELECT will remain: The command-processing functionality of DELECT has been moved into DO-COMMAND. I'm guessing that DELECT will end up being a preprocessor that generates DO-COMMAND blocks; the wiki you mentioned says that a similar preprocessor is run on Draw blocks before they are sent to DO-COMMAND (the "For special draw dialects..." paragraph). | |
Davide: 21-Jun-2010 | How can I convert money to a number or a char ? >> to integer! $1 ** Script Error: Invalid argument: $1.00 ** Near: to integer! $1.00 >> to char! $65 ** Script Error: Invalid argument: $65.00 ** Where: halt-view ** Near: to char! $65.00 | |
Maxim: 21-Jun-2010 | decimal/money not being convertible to one another is a strange ommission in R2 | |
BrianH: 21-Jun-2010 | We did a really thorough revamp of conversion in R3. And doing the same in R2 would be comparable in scope. | |
BrianH: 21-Jun-2010 | Great way to exploit a terrible bug for the benefit of all! :) | |
Graham: 21-Jun-2010 | This is math ... not a bug | |
BrianH: 21-Jun-2010 | The type conversion is a bug. The math is the benefit. | |
Maxim: 21-Jun-2010 | if you divided by a decimal, then it should return a money type. which it does. | |
BrianH: 21-Jun-2010 | No string conversion, no floating point division(?); we have a winner! | |
Davide: 21-Jun-2010 | thanks for the quick answers! you guys are great I'm building a function that computes the challenging code for web socket protocol, It uses unsigned 32 bit integer, so I use money instead of integer, to avoid overflow. | |
BrianH: 21-Jun-2010 | Does it have to be a string, or will binary do? | |
Davide: 21-Jun-2010 | thanks ladislav, but I prefer a small routine ad hoc instead of a generic and more complex one. I have to be small with this code | |
Davide: 21-Jun-2010 | umh... but this fails if I pass a number > 2^31 | |
Davide: 22-Jun-2010 | The bug was my fault, I was using a wrong variable name. Thanks all for the help. The complete (working) function to calculate the challenging code server side in web socket protocol is: ws-chall: funct [header [string!]] [ cnt: funct [k] [ n: copy "" ns: 0 repeat x k [ if all [x >= #"0" x <= #"9"][ append n x ] if x = #" " [ ns: ns + 1 ] ] if ns = 0 [ return none ] (to decimal! n) / ns ] int-2-char: funct [n [integer! decimal!]] [ ;n: to decimal! n head insert insert insert insert make string! 4 to char! n / 16777216 to char! (n // 16777216) / 65536 to char! (n // 65536) / 256 to char! n // 256 ] attempt [ t: parse/all replace/all header crlf lf "^/" l: copy [] repeat x t [if n: find x ":" [insert tail l reduce [copy/part x (index? n) - 1 next n]]] l: head l k1: next select l "Sec-WebSocket-Key1" k2: next select l "Sec-WebSocket-Key2" k3: next next find header "^/^/" aux1: cnt k1 aux2: cnt k2 ] if any [none? aux1 none? aux2 none? k3] [return ""] to-string checksum/method rejoin [int-2-char aux1 int-2-char aux2 k3] 'md5 ] | |
Davide: 26-Jun-2010 | why join "a" find "x" "abc" gives "anone" ? Is it useful ? | |
Sunanda: 26-Jun-2010 | [Henrik was faster] so the second argument gets changed to the type of the first. Or, failing that, both are changed to string! Try these to see: join "a" [1 2 3] join 26-jun-2010 "999" | |
Davide: 26-Jun-2010 | this seems correct, but none isn't a special type? I would like to use it as "neutral value" in operations | |
Davide: 26-Jun-2010 | IMHO join "a" none should give "a" , length? none should give 0 and next none should give none | |
Fork: 26-Jun-2010 | @Davide: I've actually thought the same thing about none, with respect to joining (though I think [0 = length? none] would be unwise, just as [true = true? 0] would be a mistake). | |
Fork: 26-Jun-2010 | Yet in Rebol sometimes the "tail wags the dog"... there are often deeply entrenched reasons where some implementation detail of how X functionality is built on top of Y functionality means you get a certain behavior... like, if none didn't print as "none" it would break the reflection model or something with MOLD. The go-to person on telling you the underlying facts of the matter is generally BrianH. :) | |
Fork: 26-Jun-2010 | Rebol programming can be very much like a trapeze without a safety net. I have bent some of the rules in a dialect I made where (for instance) you can use constants or words as the clauses in if or either conditions. So you can write things like [str: either condition "truestring" "falsestring"], instead of [str: either condition ["truestring"] ["falsestring"]] | |
Davide: 26-Jun-2010 | fork you probably are right, but I still think that length? none should not stop the script with an error. Could'n it produce a "warnig" only or a catchable error instead? | |
Henrik: 26-Jun-2010 | what I do is normally wrap such code in an ALL block. NONE can mean so many things and it's best to trap a NONE where you know it appears during an operation that requires a series as input. | |
Fork: 26-Jun-2010 | But 90% of the time, when you find a Rebol decision when you are not used to the language and study it after a time you will find it was made after a lot of deliberation. | |
Fork: 26-Jun-2010 | For better or worse, this thing has been cooked and tweaked for far more than a decade... so there's a lot of experience guiding the choices, especially if you're using R3. (R2 had rather more clunky edges to it when viewed in hindsight.) | |
Henrik: 26-Jun-2010 | most of the time you're probably masking bugs - exactly. Now if all these accepted NONE and returned 0 at the end: length? find find find my-string "a" "b" "c" == 0 where would the error be? | |
Graham: 26-Jun-2010 | I think we had a similar discussion about index? .. it errors when find returns none | |
Steeve: 27-Jun-2010 | Yep, this discussion is recurring. There are pros and cons. I would like to know the opinion of Carl about this. #[none] could be a special "transient" value which impacts the behavior of DO . Allowing to passthru a chain of functions without breaking the flow. | |
BrianH: 27-Jun-2010 | The INDEX? case has been covered by a CureCode discussion, and it looks like a good idea. For LENGTH?, the same behavior of returning none when passed none would make just as much sense. Under no circumstances should INDEX? or LENGTH? return an integer when passed none, not even 0. | |
BrianH: 27-Jun-2010 | Davide, REBOL doesn't have a neutral value for any type. This is by design. What we have instead is a value that can be used to mean nothing: none. And we have control structures to convert non-values to a default value: ANY and DEFAULT. R3's control structures are built around that principle, including the changes to the ordinal functions and EXTRACT. | |
Fork: 27-Jun-2010 | Again, this is the awkward dynamic between consistency and intuition. If you can state an invariant, like "If S is a string, then append S FOO is equivalent to append S to-string FOO" (for example) then it might be like "oh, it makes sense once you know that rule". But you've got to find the layer at which people program, and this is when I start using the phrase "tail wagging the dog" because people are being asked to program at the APPEND layer so the implementation details of append should be secondary to what is sensible. | |
Graham: 27-Jun-2010 | join "a" any [ find "x" "abc" copy "" ] | |
Fork: 27-Jun-2010 | I know what you mean, as appending none to a block does add a "none". Though APPEND [A B] NONE currently seems to do the same thing as APPEND [A B] 'NONE. I would be interested to know the side effects of saying APPEND [A B] NONE gave [A B] while APPEND [A B] 'NONE gave [A B NONE]. | |
BrianH: 27-Jun-2010 | What you said to do is append none to a string. By your reaction, you wanted to append an empty string to the string. That means this (assuming that you don't know that the none is there): >> append "mystring" any [none ""] == "mystring" The need for none to be explicitly converted to other values, rather than implicitly, is an intentional design choice that has been applied to a great deal of R3. It is not an error. | |
BrianH: 27-Jun-2010 | As for the side effects of not appending none, Fork, that woulld ruin blocks that contain fixed-length records of positionally accessed data, a common useage pattern. If nothing is appended, the positions of the subsequent stuff would be off. | |
Steeve: 27-Jun-2010 | >> join "a" any [ find "x" "abc" copy "" ] pretty common idiom (though, you don't need of the copy) | |
BrianH: 27-Jun-2010 | Why would we need to convert #[none] to 'none ? The value #[none] is more useful; because of ANY and DEFAULT. Neither of those will convert 'none to a default value, but they will convert #[none]. | |
Davide: 27-Jun-2010 | >> join "a" any [ find "x" "abc" copy "" ] I will use this idiom, thanks. But still I think that having "idioms" in programming language is a symptom of something not really correct. | |
BrianH: 27-Jun-2010 | All programming languages are inherently limited. You have a limited number of built-in words and concepts. Because of this there will only be a limited number of concepts that can directly be supported by the language without combining words. To form other concepts, you need to combine words - aka composing functions. As more concepts are shared, the best combination of words to express them will be shared and refined as well. These combinations of words are idioms. Idioms are not a symptom of something which is not correct, quite the opposite. The ability to form idioms is a sign of a healthy language that is more powerful, able to handle more complex concepts. Idioms are always an inherently good thing. | |
BrianH: 27-Jun-2010 | The trick for language design is not to get rid of idioms, but instead to do whatever you can to make possible to make simple idioms more powerful. This is usually done by making the different parts of the language fit together better, and and more flexibly. You get more flexibility by making the core concepts simpler, and then making them as widely and consistently applicable as you can without breaking them. Consistency is key here, and not just key in a positive way. More consistency means that you can fit more of the parts of the language together better. However, you have to limit consistency to places where it makes sense, and has real benefits. False consistency can get in your way. | |
Davide: 30-Jun-2010 | >> append #{} 15 == #{3135} >> append #{} "15" == #{3135} Why if I append an integer to a binary it is first converted to an ascii string? IMHO it should be like this: >> append #{} to-char 15 == #{0F} | |
BrianH: 30-Jun-2010 | We don't yet have a CureCode project for R2. | |
BrianH: 30-Jun-2010 | Nice! But you have to do it in sections of 10 or less, due to the length of tuples; not a complaint, a gotcha to look out for. | |
jack-ort: 2-Jul-2010 | Hello - hope someone can find the newbie mistake I'm making here. Wanted to use REBOL to tackle a need to get data from Salesforce using their SOAP API. New to SOAP, WSDL and Salesforce, but using SoapUI mananged to do this POST (edited only to hide personal info): POST https://login.salesforce.com/services/Soap/u/19.0HTTP/1.1 Accept-Encoding: gzip,deflate Content-Type: text/xml;charset=UTF-8 SOAPAction: "" User-Agent: Jakarta Commons-HttpClient/3.1 Host: login.salesforce.com Content-Length: 525 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client></urn:client> <urn:defaultNamespace></urn:defaultNamespace> </urn:CallOptions> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>[jort-:-xxxxxxxxxxxxx-:-com]</urn:username> <urn:password>xxxxxxxxxx78l6g7iFac5uaviDnJLFxxxxx</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope> and get the desired response: HTTP/1.1 200 OK Server: Content-Encoding: gzip Content-Type: text/xml; charset=utf-8 Content-Length: 736 Date: Fri, 02 Jul 2010 20:32:14 GMT <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><loginResponse> ...... Then using SoapUI I am able to send a successful Logout message. Using REBOL 2.7.7.3.1, I created an "upload" string containing the POST block above without the "POST " at the beginning, set my url to: >> url == https://login.salesforce.com/services/Soap/u/19.0 and tried this: >> response: read/custom url reduce ['POST upload] but consistently get a Server 500 error: ** User Error: Error. Target url: https://login.salesforce.com:443/services/Soap/u/19.0 could not be retrieved. Se rver response: HTTP... ** Near: response: read/custom url reduce ['POST upload] For completeness, here's the upload value: >> print mold upload {https://login.salesforce.com/services/Soap/u/19.0HTTP/1.1 Accept-Encoding: gzip,deflate Content-Type: text/xml;charset=UTF-8 SOAPAction: "" User-Agent: Jakarta Commons-HttpClient/3.1 Host: login.salesforce.com Content-Length: 525 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com"> <soapenv:Header> <urn:CallOptions> <urn:client></urn:client> <urn:defaultNamespace></urn:defaultNamespace> </urn:CallOptions> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>[jort-:-researchpoint-:-com]</urn:username> <urn:password>metrics12378l6g7iFac5uaviDnJLFVprDl</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>} Would appreciate any help you can give! | |
Graham: 2-Jul-2010 | Why is there a one byte difference in the cotent-lengths? | |
jack-ort: 2-Jul-2010 | Hi Graham - sorry to be dense - how did you determine there was a 1 byte difference in length? Re. the soap body format, I just copied/pasted from the SoapUI screen....I will have to test and see if the newlines are the problem - Thanks for the suggestion! | |
Izkata: 2-Jul-2010 | I also see a 1 byte difference in length - all I did was open Rebol and use length? - and it returned 526. | |
jack-ort: 2-Aug-2010 | Thought I'd see this question asked before, but couldn't find it. Using makdedoc2 to create a simple table, I cannot figure out how to present an empty cell. Following the table example from http://www.rebol.net/docs/makedoc/fastmd.html: ===Table \table Column 1 Column 2 Column 3 =row Row 1, col 1 Row 1, col 2 Row 1, col 3 =row Row 2, col 1 Row 2, col 2 Row 2, col 3 /table But an extra blank row will not give you a blank cell - consequently, my cell values are shifting to the left to fill in the empty cells. Is there a solution to this? Many thanks in advance for your help! | |
jack-ort: 2-Aug-2010 | Hi Henrik! the "" hold the place, so that my cells no longer shift over, but that value gets displayed in my output as a pair of double quotes, when I'd prefer to see a blank. This output is headed to an Excel spreadsheet, for what that's worth. | |
Gregg: 2-Aug-2010 | IIRC, I used a dash for empty cells. For export purposes, if you really need it blank, you may need to use a special value and then post-process it out. I don't know how to do a blank value right off either. All the normal tricks of NONE or () won't work in this context. | |
jack-ort: 2-Aug-2010 | everything I try seems to get taken as a literal value, so a dash will be a dash. Extra blank lines do not work, if that's what you mean by folded. | |
Gregg: 2-Aug-2010 | Yes, I used a dash as a dash, knowing that meant the cell was empty. I think post-processing is the way to go. | |
Maxim: 2-Aug-2010 | especially since all it needs is a replace/all :-) | |
Gregg: 2-Aug-2010 | Between a WRITE and a READ. :-) | |
Anton: 2-Aug-2010 | I haven't used make-doc for a long while, but maybe you can insert HTML's | |
Anton: 2-Aug-2010 | Then there's ascii char 160, which you can generate in rebol with to-char 160. I think they call it a 'hard space' or something. | |
BrianH: 20-Aug-2010 | Don't worry, it was a fake account. | |
florin: 28-Aug-2010 | What is the issue! datatype? A release? A specification? A problem? | |
BrianH: 29-Aug-2010 | The issue! type is a string type that is used for special purposes. One of those pruposes is a preprocessor script called prebol, which is used by the SDK. If you saw #do in a script it is likely a prebol directive. | |
srwill: 1-Nov-2010 | Hi. So is this the correct group to ask a codingn question? | |
srwill: 1-Nov-2010 | I''m trying to understand this language, sometimes getting it, sometimes not. Anyway here's my question. In VID, I have a layout. I want to put random images in 3 columns with 5 rows. The images are stored together in a single binary file. (this is a mod of the card game on Nick's tutorial site). So I read in the images into a series, after I set the layout. But how do add those to the layout? Here's my current code: do %cards.r the-tableau: layout [ size 320x480 backdrop 0.170.0 across at 30x20 tc1: box 80x100 teal tc2: box 80x100 teal tc3: box 80x100 teal return at 30x130 tc4: box 80x100 teal tc100: box 80x100 coal tc5: box 80x100 teal return at 30x240 tc6: box 80x100 teal tc200: box 80x100 coal tc7: box 80x100 teal return at 30x350 tc8: box 80x100 teal tc9: box 80x100 teal tc10: box 80x100 teal ] foreach [card label num color pos] cards [ dimg: load to-binary decompress (card) append deck-cards dimg ;feel movestyle throw-away-label: label append deck-cards-num num append deck-cards-color color throw-away-pos: pos ] view/new the-tableau do-events | |
srwill: 1-Nov-2010 | i want to replace each of the boxes in the layout with a random image from deck-cards. | |
srwill: 1-Nov-2010 | That does help, thanks! But still having some trouble seeing what's going on. I see what random-card does, I think. length? card-images returns how many are in the series of card-images. Then random returns a number based on length?. And pick chooses one of the card-images based on the random number. But what is happening in the foreach? It iterates over the images in the layout, correct? The c is just an arbitrary variable, it could be anything, right? | |
Maxim: 1-Nov-2010 | in REBOL all functions return a value, even if you do not use the return word (its actually better not to use return explicitely, since its faster) so the random-card function returns an image! from the card-images block. the set-face function applies the image to its default meaning for that style. | |
srwill: 1-Nov-2010 | The plan was to read card at random into a block called the-deck, then remove them one at a time, and add them to another block called the-tableau. | |
Maxim: 1-Nov-2010 | I've got important work to do right now, but if you can wait, I can give you a working solution later. | |
srwill: 1-Nov-2010 | No, tableau is a term I seem to recall from an old According to Hoyle card rules book, meaning the layout of the cards to be played. | |
Maxim: 2-Nov-2010 | Note I added a bit of meat to the do-events topic raised by Graham, as an extra answer. and yes... it would be swell if you rate the answer as the final one (shameless I know, but worth the time and effort Me thinks ;-) | |
rjshanley: 23-Nov-2010 | Is there a way to make objects a and b such that operations like a + b make sense? Like a complex number object. | |
Sunanda: 23-Nov-2010 | Geomol has done a complex number library.....Discussion is here: http://www.rebol.org/aga-display-posts.r?offset=0&post=r3wp381x1804 | |
rjshanley: 24-Nov-2010 | Geomol's complex number library represents a workable approach to implementing a large integer math library. But has anyone already implemented one? That is, bc's ability to do +, -, *, and / on very large numbers? I've been trying to call bc from REBOL using the CALL stmt, but success has so far eluded me. | |
Sunanda: 24-Nov-2010 | There is this: http://www.rebol.org/view-script.r?script=bignumbers.r But (from a quick squint) it handles numbers as strings. That may be less effective than the usual bignum approach [which, in REBOL terms, might be a block of 32-bit binaries] | |
BrianH: 24-Nov-2010 | Isn't there a libbc? | |
rjshanley: 24-Nov-2010 | The block of binaries would give better performance, but the string approach might be fast enough. I'll take a look at it. Thx. | |
Sunanda: 24-Nov-2010 | Strings are probably fine for 12 or 13 digit numbers. REBOL3 has 64-bit integers, so that is well within range of a native REBOL 3 INT. Is R3 a possibility for your project? | |
rjshanley: 24-Nov-2010 | Yes, it is. Native would be great. I just tried some simple stuff on R3 so I'll experiment further. Thanks a lot. |
33201 / 64608 | 1 | 2 | 3 | 4 | 5 | ... | 331 | 332 | [333] | 334 | 335 | ... | 643 | 644 | 645 | 646 | 647 |