openBaseopenStringletindex_optsc=trySome(indexsc)withNot_found->Noneletis_prefix?from:(pos=0)~prefix:substr=letstr_len=String.lengthstrinletsub_len=String.lengthsubinifpos+sub_len>str_lenthenfalseelseletreciteri=ifstr.[pos+i]<>sub.[i]thenfalseelseleti'=i+1inifi'=sub_lenthentrueelseiteri'initer0letindex_string_fromstrpossub=letsub_len=String.lengthsubinifsub_len=0thenposelseletlimit=String.lengthstr-sub_leninletreciteri=ifi>limitthenraiseNot_foundelseifis_prefixstr~from:i~prefix:subthenielseiter(i+1)initerposletis_postfix~postfix:substr=is_prefix~from:(String.lengthstr-String.lengthsub)~prefix:substrletrecindex_recslimic=ifi>=limthenNoneelseifString.unsafe_getsi=cthenSomeielseindex_recslim(i+1)c;;letindex_from_tosfromto_c=letl=String.lengthsiniffrom<0||from>to_||to_>=ltheninvalid_arg"Xstring.index_from_to"elseindex_recs(to_+1)fromc;;letchop_newlines=letlen=String.lengthsiniflen>1&&s.[len-1]='\n'theniflen>2&&s.[len-2]='\r'thenString.subs0(len-2)elseString.subs0(len-1)elsesletsub_from_tosfromto_=iffrom>to_theninvalid_arg"sub_from_to";String.subsfrom(to_-from+1)letsplit_by_newlines=letlength=String.lengthsinletrecauxststart_pospos=ifpos=lengththenList.revstelsematchs.[pos]with|'\r'|'\n'->letst=String.subsstart_pos(pos-start_pos)::stinskipst(pos+1)|_->auxststart_pos(pos+1)andskipstpos=ifpos=lengththenList.revstelsematchs.[pos]with|'\r'|'\n'->skipst(pos+1)|_->auxstpos(pos+1)inaux[]00(* split a string according to char_sep predicate *)letsplitchar_sepstr=letlen=String.lengthstriniflen=0then[]elseletrecskip_sepcur=ifcur>=lenthencurelseifchar_sepstr.[cur]thenskip_sep(succcur)elsecurinletrecsplitbegcur=ifcur>=lenthenifbeg=curthen[]else[String.substrbeg(len-beg)]elseifchar_sepstr.[cur]thenletnextw=skip_sepcurin(String.substrbeg(cur-beg))::(splitnextwnextw)elsesplitbeg(succcur)inletwstart=skip_sep0insplitwstartwstartletmake1=String.make1moduleSet=Xset.Make(structtypet=stringletcompare(x:string)y=comparexyend)moduleOpen=structletchop_newline=chop_newlineletsplit_by_newline=split_by_newlineendletsplit_atlenstr=String.substr0len,String.substrlen(String.lengthstr-len)lettakelenstr=String.substr0lenletdroplenstr=String.substrlen(String.lengthstr-len)letscani_leftfacc?from?to_s=letfrom=Option.defaultfrom(fun()->0)inletto_=Option.defaultto_(fun()->String.lengths-1)inletrecfoldaccpos=ifpos>=to_thenaccelsematchfposacc&String.unsafe_getsposwith|`Continueacc->foldacc&pos+1|`Stopacc->accinfoldaccfromletfoldi_leftfaccs=scani_leftfaccs