bpmn-viewer.development.js 539 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379
  1. /*!
  2. * bpmn-js - bpmn-viewer v16.3.2
  3. *
  4. * Copyright (c) 2014-present, camunda Services GmbH
  5. *
  6. * Released under the bpmn.io license
  7. * http://bpmn.io/license
  8. *
  9. * Source Code: https://github.com/bpmn-io/bpmn-js
  10. *
  11. * Date: 2024-01-09
  12. */
  13. (function (global, factory) {
  14. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  15. typeof define === 'function' && define.amd ? define(factory) :
  16. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.BpmnJS = factory());
  17. })(this, (function () { 'use strict';
  18. function e(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}));}
  19. /**
  20. * Flatten array, one level deep.
  21. *
  22. * @template T
  23. *
  24. * @param {T[][]} arr
  25. *
  26. * @return {T[]}
  27. */
  28. const nativeToString$1 = Object.prototype.toString;
  29. const nativeHasOwnProperty$1 = Object.prototype.hasOwnProperty;
  30. function isUndefined$2(obj) {
  31. return obj === undefined;
  32. }
  33. function isDefined(obj) {
  34. return obj !== undefined;
  35. }
  36. function isNil(obj) {
  37. return obj == null;
  38. }
  39. function isArray$2(obj) {
  40. return nativeToString$1.call(obj) === '[object Array]';
  41. }
  42. function isObject(obj) {
  43. return nativeToString$1.call(obj) === '[object Object]';
  44. }
  45. function isNumber(obj) {
  46. return nativeToString$1.call(obj) === '[object Number]';
  47. }
  48. /**
  49. * @param {any} obj
  50. *
  51. * @return {boolean}
  52. */
  53. function isFunction(obj) {
  54. const tag = nativeToString$1.call(obj);
  55. return (
  56. tag === '[object Function]' ||
  57. tag === '[object AsyncFunction]' ||
  58. tag === '[object GeneratorFunction]' ||
  59. tag === '[object AsyncGeneratorFunction]' ||
  60. tag === '[object Proxy]'
  61. );
  62. }
  63. function isString(obj) {
  64. return nativeToString$1.call(obj) === '[object String]';
  65. }
  66. /**
  67. * Return true, if target owns a property with the given key.
  68. *
  69. * @param {Object} target
  70. * @param {String} key
  71. *
  72. * @return {Boolean}
  73. */
  74. function has$1(target, key) {
  75. return nativeHasOwnProperty$1.call(target, key);
  76. }
  77. /**
  78. * @template T
  79. * @typedef { (
  80. * ((e: T) => boolean) |
  81. * ((e: T, idx: number) => boolean) |
  82. * ((e: T, key: string) => boolean) |
  83. * string |
  84. * number
  85. * ) } Matcher
  86. */
  87. /**
  88. * @template T
  89. * @template U
  90. *
  91. * @typedef { (
  92. * ((e: T) => U) | string | number
  93. * ) } Extractor
  94. */
  95. /**
  96. * @template T
  97. * @typedef { (val: T, key: any) => boolean } MatchFn
  98. */
  99. /**
  100. * @template T
  101. * @typedef { T[] } ArrayCollection
  102. */
  103. /**
  104. * @template T
  105. * @typedef { { [key: string]: T } } StringKeyValueCollection
  106. */
  107. /**
  108. * @template T
  109. * @typedef { { [key: number]: T } } NumberKeyValueCollection
  110. */
  111. /**
  112. * @template T
  113. * @typedef { StringKeyValueCollection<T> | NumberKeyValueCollection<T> } KeyValueCollection
  114. */
  115. /**
  116. * @template T
  117. * @typedef { KeyValueCollection<T> | ArrayCollection<T> } Collection
  118. */
  119. /**
  120. * Find element in collection.
  121. *
  122. * @template T
  123. * @param {Collection<T>} collection
  124. * @param {Matcher<T>} matcher
  125. *
  126. * @return {Object}
  127. */
  128. function find(collection, matcher) {
  129. const matchFn = toMatcher(matcher);
  130. let match;
  131. forEach$1(collection, function(val, key) {
  132. if (matchFn(val, key)) {
  133. match = val;
  134. return false;
  135. }
  136. });
  137. return match;
  138. }
  139. /**
  140. * Find element index in collection.
  141. *
  142. * @template T
  143. * @param {Collection<T>} collection
  144. * @param {Matcher<T>} matcher
  145. *
  146. * @return {number}
  147. */
  148. function findIndex(collection, matcher) {
  149. const matchFn = toMatcher(matcher);
  150. let idx = isArray$2(collection) ? -1 : undefined;
  151. forEach$1(collection, function(val, key) {
  152. if (matchFn(val, key)) {
  153. idx = key;
  154. return false;
  155. }
  156. });
  157. return idx;
  158. }
  159. /**
  160. * Filter elements in collection.
  161. *
  162. * @template T
  163. * @param {Collection<T>} collection
  164. * @param {Matcher<T>} matcher
  165. *
  166. * @return {T[]} result
  167. */
  168. function filter(collection, matcher) {
  169. const matchFn = toMatcher(matcher);
  170. let result = [];
  171. forEach$1(collection, function(val, key) {
  172. if (matchFn(val, key)) {
  173. result.push(val);
  174. }
  175. });
  176. return result;
  177. }
  178. /**
  179. * Iterate over collection; returning something
  180. * (non-undefined) will stop iteration.
  181. *
  182. * @template T
  183. * @param {Collection<T>} collection
  184. * @param { ((item: T, idx: number) => (boolean|void)) | ((item: T, key: string) => (boolean|void)) } iterator
  185. *
  186. * @return {T} return result that stopped the iteration
  187. */
  188. function forEach$1(collection, iterator) {
  189. let val,
  190. result;
  191. if (isUndefined$2(collection)) {
  192. return;
  193. }
  194. const convertKey = isArray$2(collection) ? toNum$1 : identity$1;
  195. for (let key in collection) {
  196. if (has$1(collection, key)) {
  197. val = collection[key];
  198. result = iterator(val, convertKey(key));
  199. if (result === false) {
  200. return val;
  201. }
  202. }
  203. }
  204. }
  205. /**
  206. * Reduce collection, returning a single result.
  207. *
  208. * @template T
  209. * @template V
  210. *
  211. * @param {Collection<T>} collection
  212. * @param {(result: V, entry: T, index: any) => V} iterator
  213. * @param {V} result
  214. *
  215. * @return {V} result returned from last iterator
  216. */
  217. function reduce(collection, iterator, result) {
  218. forEach$1(collection, function(value, idx) {
  219. result = iterator(result, value, idx);
  220. });
  221. return result;
  222. }
  223. /**
  224. * Return true if every element in the collection
  225. * matches the criteria.
  226. *
  227. * @param {Object|Array} collection
  228. * @param {Function} matcher
  229. *
  230. * @return {Boolean}
  231. */
  232. function every(collection, matcher) {
  233. return !!reduce(collection, function(matches, val, key) {
  234. return matches && matcher(val, key);
  235. }, true);
  236. }
  237. /**
  238. * Return true if some elements in the collection
  239. * match the criteria.
  240. *
  241. * @param {Object|Array} collection
  242. * @param {Function} matcher
  243. *
  244. * @return {Boolean}
  245. */
  246. function some(collection, matcher) {
  247. return !!find(collection, matcher);
  248. }
  249. /**
  250. * Transform a collection into another collection
  251. * by piping each member through the given fn.
  252. *
  253. * @param {Object|Array} collection
  254. * @param {Function} fn
  255. *
  256. * @return {Array} transformed collection
  257. */
  258. function map$1(collection, fn) {
  259. let result = [];
  260. forEach$1(collection, function(val, key) {
  261. result.push(fn(val, key));
  262. });
  263. return result;
  264. }
  265. /**
  266. * Create an object pattern matcher.
  267. *
  268. * @example
  269. *
  270. * ```javascript
  271. * const matcher = matchPattern({ id: 1 });
  272. *
  273. * let element = find(elements, matcher);
  274. * ```
  275. *
  276. * @template T
  277. *
  278. * @param {T} pattern
  279. *
  280. * @return { (el: any) => boolean } matcherFn
  281. */
  282. function matchPattern(pattern) {
  283. return function(el) {
  284. return every(pattern, function(val, key) {
  285. return el[key] === val;
  286. });
  287. };
  288. }
  289. /**
  290. * @template T
  291. * @param {Matcher<T>} matcher
  292. *
  293. * @return {MatchFn<T>}
  294. */
  295. function toMatcher(matcher) {
  296. return isFunction(matcher) ? matcher : (e) => {
  297. return e === matcher;
  298. };
  299. }
  300. function identity$1(arg) {
  301. return arg;
  302. }
  303. function toNum$1(arg) {
  304. return Number(arg);
  305. }
  306. /* global setTimeout clearTimeout */
  307. /**
  308. * @typedef { {
  309. * (...args: any[]): any;
  310. * flush: () => void;
  311. * cancel: () => void;
  312. * } } DebouncedFunction
  313. */
  314. /**
  315. * Debounce fn, calling it only once if the given time
  316. * elapsed between calls.
  317. *
  318. * Lodash-style the function exposes methods to `#clear`
  319. * and `#flush` to control internal behavior.
  320. *
  321. * @param {Function} fn
  322. * @param {Number} timeout
  323. *
  324. * @return {DebouncedFunction} debounced function
  325. */
  326. function debounce(fn, timeout) {
  327. let timer;
  328. let lastArgs;
  329. let lastThis;
  330. let lastNow;
  331. function fire(force) {
  332. let now = Date.now();
  333. let scheduledDiff = force ? 0 : (lastNow + timeout) - now;
  334. if (scheduledDiff > 0) {
  335. return schedule(scheduledDiff);
  336. }
  337. fn.apply(lastThis, lastArgs);
  338. clear();
  339. }
  340. function schedule(timeout) {
  341. timer = setTimeout(fire, timeout);
  342. }
  343. function clear() {
  344. if (timer) {
  345. clearTimeout(timer);
  346. }
  347. timer = lastNow = lastArgs = lastThis = undefined;
  348. }
  349. function flush() {
  350. if (timer) {
  351. fire(true);
  352. }
  353. clear();
  354. }
  355. /**
  356. * @type { DebouncedFunction }
  357. */
  358. function callback(...args) {
  359. lastNow = Date.now();
  360. lastArgs = args;
  361. lastThis = this;
  362. // ensure an execution is scheduled
  363. if (!timer) {
  364. schedule(timeout);
  365. }
  366. }
  367. callback.flush = flush;
  368. callback.cancel = clear;
  369. return callback;
  370. }
  371. /**
  372. * Bind function against target <this>.
  373. *
  374. * @param {Function} fn
  375. * @param {Object} target
  376. *
  377. * @return {Function} bound function
  378. */
  379. function bind$2(fn, target) {
  380. return fn.bind(target);
  381. }
  382. /**
  383. * Convenience wrapper for `Object.assign`.
  384. *
  385. * @param {Object} target
  386. * @param {...Object} others
  387. *
  388. * @return {Object} the target
  389. */
  390. function assign$1(target, ...others) {
  391. return Object.assign(target, ...others);
  392. }
  393. /**
  394. * Sets a nested property of a given object to the specified value.
  395. *
  396. * This mutates the object and returns it.
  397. *
  398. * @template T
  399. *
  400. * @param {T} target The target of the set operation.
  401. * @param {(string|number)[]} path The path to the nested value.
  402. * @param {any} value The value to set.
  403. *
  404. * @return {T}
  405. */
  406. function set$1(target, path, value) {
  407. let currentTarget = target;
  408. forEach$1(path, function(key, idx) {
  409. if (typeof key !== 'number' && typeof key !== 'string') {
  410. throw new Error('illegal key type: ' + typeof key + '. Key should be of type number or string.');
  411. }
  412. if (key === 'constructor') {
  413. throw new Error('illegal key: constructor');
  414. }
  415. if (key === '__proto__') {
  416. throw new Error('illegal key: __proto__');
  417. }
  418. let nextKey = path[idx + 1];
  419. let nextTarget = currentTarget[key];
  420. if (isDefined(nextKey) && isNil(nextTarget)) {
  421. nextTarget = currentTarget[key] = isNaN(+nextKey) ? {} : [];
  422. }
  423. if (isUndefined$2(nextKey)) {
  424. if (isUndefined$2(value)) {
  425. delete currentTarget[key];
  426. } else {
  427. currentTarget[key] = value;
  428. }
  429. } else {
  430. currentTarget = nextTarget;
  431. }
  432. });
  433. return target;
  434. }
  435. /**
  436. * Pick properties from the given target.
  437. *
  438. * @template T
  439. * @template {any[]} V
  440. *
  441. * @param {T} target
  442. * @param {V} properties
  443. *
  444. * @return Pick<T, V>
  445. */
  446. function pick(target, properties) {
  447. let result = {};
  448. let obj = Object(target);
  449. forEach$1(properties, function(prop) {
  450. if (prop in obj) {
  451. result[prop] = target[prop];
  452. }
  453. });
  454. return result;
  455. }
  456. /**
  457. * Pick all target properties, excluding the given ones.
  458. *
  459. * @template T
  460. * @template {any[]} V
  461. *
  462. * @param {T} target
  463. * @param {V} properties
  464. *
  465. * @return {Omit<T, V>} target
  466. */
  467. function omit(target, properties) {
  468. let result = {};
  469. let obj = Object(target);
  470. forEach$1(obj, function(prop, key) {
  471. if (properties.indexOf(key) === -1) {
  472. result[key] = prop;
  473. }
  474. });
  475. return result;
  476. }
  477. var DEFAULT_RENDER_PRIORITY$1 = 1000;
  478. /**
  479. * @typedef {import('../core/Types').ElementLike} Element
  480. * @typedef {import('../core/Types').ConnectionLike} Connection
  481. * @typedef {import('../core/Types').ShapeLike} Shape
  482. *
  483. * @typedef {import('../core/EventBus').default} EventBus
  484. */
  485. /**
  486. * The base implementation of shape and connection renderers.
  487. *
  488. * @param {EventBus} eventBus
  489. * @param {number} [renderPriority=1000]
  490. */
  491. function BaseRenderer(eventBus, renderPriority) {
  492. var self = this;
  493. renderPriority = renderPriority || DEFAULT_RENDER_PRIORITY$1;
  494. eventBus.on([ 'render.shape', 'render.connection' ], renderPriority, function(evt, context) {
  495. var type = evt.type,
  496. element = context.element,
  497. visuals = context.gfx,
  498. attrs = context.attrs;
  499. if (self.canRender(element)) {
  500. if (type === 'render.shape') {
  501. return self.drawShape(visuals, element, attrs);
  502. } else {
  503. return self.drawConnection(visuals, element, attrs);
  504. }
  505. }
  506. });
  507. eventBus.on([ 'render.getShapePath', 'render.getConnectionPath' ], renderPriority, function(evt, element) {
  508. if (self.canRender(element)) {
  509. if (evt.type === 'render.getShapePath') {
  510. return self.getShapePath(element);
  511. } else {
  512. return self.getConnectionPath(element);
  513. }
  514. }
  515. });
  516. }
  517. /**
  518. * Checks whether an element can be rendered.
  519. *
  520. * @param {Element} element The element to be rendered.
  521. *
  522. * @return {boolean} Whether the element can be rendered.
  523. */
  524. BaseRenderer.prototype.canRender = function(element) {};
  525. /**
  526. * Draws a shape.
  527. *
  528. * @param {SVGElement} visuals The SVG element to draw the shape into.
  529. * @param {Shape} shape The shape to be drawn.
  530. *
  531. * @return {SVGElement} The SVG element of the shape drawn.
  532. */
  533. BaseRenderer.prototype.drawShape = function(visuals, shape) {};
  534. /**
  535. * Draws a connection.
  536. *
  537. * @param {SVGElement} visuals The SVG element to draw the connection into.
  538. * @param {Connection} connection The connection to be drawn.
  539. *
  540. * @return {SVGElement} The SVG element of the connection drawn.
  541. */
  542. BaseRenderer.prototype.drawConnection = function(visuals, connection) {};
  543. /**
  544. * Gets the SVG path of the graphical representation of a shape.
  545. *
  546. * @param {Shape} shape The shape.
  547. *
  548. * @return {string} The SVG path of the shape.
  549. */
  550. BaseRenderer.prototype.getShapePath = function(shape) {};
  551. /**
  552. * Gets the SVG path of the graphical representation of a connection.
  553. *
  554. * @param {Connection} connection The connection.
  555. *
  556. * @return {string} The SVG path of the connection.
  557. */
  558. BaseRenderer.prototype.getConnectionPath = function(connection) {};
  559. /**
  560. * @typedef { import('../model/Types').Element } Element
  561. * @typedef { import('../model/Types').ModdleElement } ModdleElement
  562. */
  563. /**
  564. * Is an element of the given BPMN type?
  565. *
  566. * @param {Element|ModdleElement} element
  567. * @param {string} type
  568. *
  569. * @return {boolean}
  570. */
  571. function is$1(element, type) {
  572. var bo = getBusinessObject(element);
  573. return bo && (typeof bo.$instanceOf === 'function') && bo.$instanceOf(type);
  574. }
  575. /**
  576. * Return true if element has any of the given types.
  577. *
  578. * @param {Element|ModdleElement} element
  579. * @param {string[]} types
  580. *
  581. * @return {boolean}
  582. */
  583. function isAny(element, types) {
  584. return some(types, function(t) {
  585. return is$1(element, t);
  586. });
  587. }
  588. /**
  589. * Return the business object for a given element.
  590. *
  591. * @param {Element|ModdleElement} element
  592. *
  593. * @return {ModdleElement}
  594. */
  595. function getBusinessObject(element) {
  596. return (element && element.businessObject) || element;
  597. }
  598. /**
  599. * Return the di object for a given element.
  600. *
  601. * @param {Element} element
  602. *
  603. * @return {ModdleElement}
  604. */
  605. function getDi(element) {
  606. return element && element.di;
  607. }
  608. /**
  609. * @typedef {import('../model/Types').Element} Element
  610. * @typedef {import('../model/Types').ModdleElement} ModdleElement
  611. */
  612. /**
  613. * @param {Element} element
  614. * @param {ModdleElement} [di]
  615. *
  616. * @return {boolean}
  617. */
  618. function isExpanded(element, di) {
  619. if (is$1(element, 'bpmn:CallActivity')) {
  620. return false;
  621. }
  622. if (is$1(element, 'bpmn:SubProcess')) {
  623. di = di || getDi(element);
  624. if (di && is$1(di, 'bpmndi:BPMNPlane')) {
  625. return true;
  626. }
  627. return di && !!di.isExpanded;
  628. }
  629. if (is$1(element, 'bpmn:Participant')) {
  630. return !!getBusinessObject(element).processRef;
  631. }
  632. return true;
  633. }
  634. /**
  635. * @param {Element} element
  636. *
  637. * @return {boolean}
  638. */
  639. function isHorizontal(element) {
  640. if (!is$1(element, 'bpmn:Participant') && !is$1(element, 'bpmn:Lane')) {
  641. return undefined;
  642. }
  643. var isHorizontal = getDi(element).isHorizontal;
  644. if (isHorizontal === undefined) {
  645. return true;
  646. }
  647. return isHorizontal;
  648. }
  649. /**
  650. * @param {Element} element
  651. *
  652. * @return {boolean}
  653. */
  654. function isEventSubProcess(element) {
  655. return element && !!getBusinessObject(element).triggeredByEvent;
  656. }
  657. /**
  658. * Checks whether a value is an instance of Connection.
  659. *
  660. * @param {any} value
  661. *
  662. * @return {boolean}
  663. */
  664. function isConnection(value) {
  665. return isObject(value) && has$1(value, 'waypoints');
  666. }
  667. /**
  668. * @typedef {import('diagram-js/lib/util/Types').Point} Point
  669. * @typedef {import('diagram-js/lib/util/Types').Rect} Rect
  670. *
  671. * @typedef {import('../model/Types').Element} Element
  672. * @typedef {import('../model/Types').ModdleElement} ModdleElement
  673. */
  674. var DEFAULT_LABEL_SIZE$1 = {
  675. width: 90,
  676. height: 20
  677. };
  678. var FLOW_LABEL_INDENT = 15;
  679. /**
  680. * Return true if the given semantic has an external label.
  681. *
  682. * @param {Element} semantic
  683. *
  684. * @return {boolean}
  685. */
  686. function isLabelExternal(semantic) {
  687. return is$1(semantic, 'bpmn:Event') ||
  688. is$1(semantic, 'bpmn:Gateway') ||
  689. is$1(semantic, 'bpmn:DataStoreReference') ||
  690. is$1(semantic, 'bpmn:DataObjectReference') ||
  691. is$1(semantic, 'bpmn:DataInput') ||
  692. is$1(semantic, 'bpmn:DataOutput') ||
  693. is$1(semantic, 'bpmn:SequenceFlow') ||
  694. is$1(semantic, 'bpmn:MessageFlow') ||
  695. is$1(semantic, 'bpmn:Group');
  696. }
  697. /**
  698. * Get the position of a sequence flow label.
  699. *
  700. * @param {Point[]} waypoints
  701. *
  702. * @return {Point}
  703. */
  704. function getFlowLabelPosition(waypoints) {
  705. // get the waypoints mid
  706. var mid = waypoints.length / 2 - 1;
  707. var first = waypoints[Math.floor(mid)];
  708. var second = waypoints[Math.ceil(mid + 0.01)];
  709. // get position
  710. var position = getWaypointsMid(waypoints);
  711. // calculate angle
  712. var angle = Math.atan((second.y - first.y) / (second.x - first.x));
  713. var x = position.x,
  714. y = position.y;
  715. if (Math.abs(angle) < Math.PI / 2) {
  716. y -= FLOW_LABEL_INDENT;
  717. } else {
  718. x += FLOW_LABEL_INDENT;
  719. }
  720. return { x: x, y: y };
  721. }
  722. /**
  723. * Get the middle of a number of waypoints.
  724. *
  725. * @param {Point[]} waypoints
  726. *
  727. * @return {Point}
  728. */
  729. function getWaypointsMid(waypoints) {
  730. var mid = waypoints.length / 2 - 1;
  731. var first = waypoints[Math.floor(mid)];
  732. var second = waypoints[Math.ceil(mid + 0.01)];
  733. return {
  734. x: first.x + (second.x - first.x) / 2,
  735. y: first.y + (second.y - first.y) / 2
  736. };
  737. }
  738. /**
  739. * Get the middle of the external label of an element.
  740. *
  741. * @param {Element} element
  742. *
  743. * @return {Point}
  744. */
  745. function getExternalLabelMid(element) {
  746. if (element.waypoints) {
  747. return getFlowLabelPosition(element.waypoints);
  748. } else if (is$1(element, 'bpmn:Group')) {
  749. return {
  750. x: element.x + element.width / 2,
  751. y: element.y + DEFAULT_LABEL_SIZE$1.height / 2
  752. };
  753. } else {
  754. return {
  755. x: element.x + element.width / 2,
  756. y: element.y + element.height + DEFAULT_LABEL_SIZE$1.height / 2
  757. };
  758. }
  759. }
  760. /**
  761. * Return the bounds of an elements label, parsed from the elements DI or
  762. * generated from its bounds.
  763. *
  764. * @param {ModdleElement} di
  765. * @param {Element} element
  766. *
  767. * @return {Rect}
  768. */
  769. function getExternalLabelBounds(di, element) {
  770. var mid,
  771. size,
  772. bounds,
  773. label = di.label;
  774. if (label && label.bounds) {
  775. bounds = label.bounds;
  776. size = {
  777. width: Math.max(DEFAULT_LABEL_SIZE$1.width, bounds.width),
  778. height: bounds.height
  779. };
  780. mid = {
  781. x: bounds.x + bounds.width / 2,
  782. y: bounds.y + bounds.height / 2
  783. };
  784. } else {
  785. mid = getExternalLabelMid(element);
  786. size = DEFAULT_LABEL_SIZE$1;
  787. }
  788. return assign$1({
  789. x: mid.x - size.width / 2,
  790. y: mid.y - size.height / 2
  791. }, size);
  792. }
  793. /**
  794. * @param {ModdleElement} semantic
  795. *
  796. * @returns {string}
  797. */
  798. function getLabelAttr(semantic) {
  799. if (
  800. is$1(semantic, 'bpmn:FlowElement') ||
  801. is$1(semantic, 'bpmn:Participant') ||
  802. is$1(semantic, 'bpmn:Lane') ||
  803. is$1(semantic, 'bpmn:SequenceFlow') ||
  804. is$1(semantic, 'bpmn:MessageFlow') ||
  805. is$1(semantic, 'bpmn:DataInput') ||
  806. is$1(semantic, 'bpmn:DataOutput')
  807. ) {
  808. return 'name';
  809. }
  810. if (is$1(semantic, 'bpmn:TextAnnotation')) {
  811. return 'text';
  812. }
  813. if (is$1(semantic, 'bpmn:Group')) {
  814. return 'categoryValueRef';
  815. }
  816. }
  817. /**
  818. * @param {ModdleElement} semantic
  819. *
  820. * @returns {string}
  821. */
  822. function getCategoryValue(semantic) {
  823. var categoryValueRef = semantic['categoryValueRef'];
  824. if (!categoryValueRef) {
  825. return '';
  826. }
  827. return categoryValueRef.value || '';
  828. }
  829. /**
  830. * @param {Element} element
  831. *
  832. * @return {string}
  833. */
  834. function getLabel(element) {
  835. var semantic = element.businessObject,
  836. attr = getLabelAttr(semantic);
  837. if (attr) {
  838. if (attr === 'categoryValueRef') {
  839. return getCategoryValue(semantic);
  840. }
  841. return semantic[attr] || '';
  842. }
  843. }
  844. function ensureImported(element, target) {
  845. if (element.ownerDocument !== target.ownerDocument) {
  846. try {
  847. // may fail on webkit
  848. return target.ownerDocument.importNode(element, true);
  849. } catch (e) {
  850. // ignore
  851. }
  852. }
  853. return element;
  854. }
  855. /**
  856. * appendTo utility
  857. */
  858. /**
  859. * Append a node to a target element and return the appended node.
  860. *
  861. * @param {SVGElement} element
  862. * @param {SVGElement} target
  863. *
  864. * @return {SVGElement} the appended node
  865. */
  866. function appendTo(element, target) {
  867. return target.appendChild(ensureImported(element, target));
  868. }
  869. /**
  870. * append utility
  871. */
  872. /**
  873. * Append a node to an element
  874. *
  875. * @param {SVGElement} element
  876. * @param {SVGElement} node
  877. *
  878. * @return {SVGElement} the element
  879. */
  880. function append(target, node) {
  881. appendTo(node, target);
  882. return target;
  883. }
  884. /**
  885. * attribute accessor utility
  886. */
  887. var LENGTH_ATTR = 2;
  888. var CSS_PROPERTIES = {
  889. 'alignment-baseline': 1,
  890. 'baseline-shift': 1,
  891. 'clip': 1,
  892. 'clip-path': 1,
  893. 'clip-rule': 1,
  894. 'color': 1,
  895. 'color-interpolation': 1,
  896. 'color-interpolation-filters': 1,
  897. 'color-profile': 1,
  898. 'color-rendering': 1,
  899. 'cursor': 1,
  900. 'direction': 1,
  901. 'display': 1,
  902. 'dominant-baseline': 1,
  903. 'enable-background': 1,
  904. 'fill': 1,
  905. 'fill-opacity': 1,
  906. 'fill-rule': 1,
  907. 'filter': 1,
  908. 'flood-color': 1,
  909. 'flood-opacity': 1,
  910. 'font': 1,
  911. 'font-family': 1,
  912. 'font-size': LENGTH_ATTR,
  913. 'font-size-adjust': 1,
  914. 'font-stretch': 1,
  915. 'font-style': 1,
  916. 'font-variant': 1,
  917. 'font-weight': 1,
  918. 'glyph-orientation-horizontal': 1,
  919. 'glyph-orientation-vertical': 1,
  920. 'image-rendering': 1,
  921. 'kerning': 1,
  922. 'letter-spacing': 1,
  923. 'lighting-color': 1,
  924. 'marker': 1,
  925. 'marker-end': 1,
  926. 'marker-mid': 1,
  927. 'marker-start': 1,
  928. 'mask': 1,
  929. 'opacity': 1,
  930. 'overflow': 1,
  931. 'pointer-events': 1,
  932. 'shape-rendering': 1,
  933. 'stop-color': 1,
  934. 'stop-opacity': 1,
  935. 'stroke': 1,
  936. 'stroke-dasharray': 1,
  937. 'stroke-dashoffset': 1,
  938. 'stroke-linecap': 1,
  939. 'stroke-linejoin': 1,
  940. 'stroke-miterlimit': 1,
  941. 'stroke-opacity': 1,
  942. 'stroke-width': LENGTH_ATTR,
  943. 'text-anchor': 1,
  944. 'text-decoration': 1,
  945. 'text-rendering': 1,
  946. 'unicode-bidi': 1,
  947. 'visibility': 1,
  948. 'word-spacing': 1,
  949. 'writing-mode': 1
  950. };
  951. function getAttribute(node, name) {
  952. if (CSS_PROPERTIES[name]) {
  953. return node.style[name];
  954. } else {
  955. return node.getAttributeNS(null, name);
  956. }
  957. }
  958. function setAttribute(node, name, value) {
  959. var hyphenated = name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
  960. var type = CSS_PROPERTIES[hyphenated];
  961. if (type) {
  962. // append pixel unit, unless present
  963. if (type === LENGTH_ATTR && typeof value === 'number') {
  964. value = String(value) + 'px';
  965. }
  966. node.style[hyphenated] = value;
  967. } else {
  968. node.setAttributeNS(null, name, value);
  969. }
  970. }
  971. function setAttributes(node, attrs) {
  972. var names = Object.keys(attrs), i, name;
  973. for (i = 0, name; (name = names[i]); i++) {
  974. setAttribute(node, name, attrs[name]);
  975. }
  976. }
  977. /**
  978. * Gets or sets raw attributes on a node.
  979. *
  980. * @param {SVGElement} node
  981. * @param {Object} [attrs]
  982. * @param {String} [name]
  983. * @param {String} [value]
  984. *
  985. * @return {String}
  986. */
  987. function attr$1(node, name, value) {
  988. if (typeof name === 'string') {
  989. if (value !== undefined) {
  990. setAttribute(node, name, value);
  991. } else {
  992. return getAttribute(node, name);
  993. }
  994. } else {
  995. setAttributes(node, name);
  996. }
  997. return node;
  998. }
  999. /**
  1000. * Taken from https://github.com/component/classes
  1001. *
  1002. * Without the component bits.
  1003. */
  1004. /**
  1005. * toString reference.
  1006. */
  1007. const toString$1 = Object.prototype.toString;
  1008. /**
  1009. * Wrap `el` in a `ClassList`.
  1010. *
  1011. * @param {Element} el
  1012. * @return {ClassList}
  1013. * @api public
  1014. */
  1015. function classes$1(el) {
  1016. return new ClassList$1(el);
  1017. }
  1018. function ClassList$1(el) {
  1019. if (!el || !el.nodeType) {
  1020. throw new Error('A DOM element reference is required');
  1021. }
  1022. this.el = el;
  1023. this.list = el.classList;
  1024. }
  1025. /**
  1026. * Add class `name` if not already present.
  1027. *
  1028. * @param {String} name
  1029. * @return {ClassList}
  1030. * @api public
  1031. */
  1032. ClassList$1.prototype.add = function(name) {
  1033. this.list.add(name);
  1034. return this;
  1035. };
  1036. /**
  1037. * Remove class `name` when present, or
  1038. * pass a regular expression to remove
  1039. * any which match.
  1040. *
  1041. * @param {String|RegExp} name
  1042. * @return {ClassList}
  1043. * @api public
  1044. */
  1045. ClassList$1.prototype.remove = function(name) {
  1046. if ('[object RegExp]' == toString$1.call(name)) {
  1047. return this.removeMatching(name);
  1048. }
  1049. this.list.remove(name);
  1050. return this;
  1051. };
  1052. /**
  1053. * Remove all classes matching `re`.
  1054. *
  1055. * @param {RegExp} re
  1056. * @return {ClassList}
  1057. * @api private
  1058. */
  1059. ClassList$1.prototype.removeMatching = function(re) {
  1060. const arr = this.array();
  1061. for (let i = 0; i < arr.length; i++) {
  1062. if (re.test(arr[i])) {
  1063. this.remove(arr[i]);
  1064. }
  1065. }
  1066. return this;
  1067. };
  1068. /**
  1069. * Toggle class `name`, can force state via `force`.
  1070. *
  1071. * For browsers that support classList, but do not support `force` yet,
  1072. * the mistake will be detected and corrected.
  1073. *
  1074. * @param {String} name
  1075. * @param {Boolean} force
  1076. * @return {ClassList}
  1077. * @api public
  1078. */
  1079. ClassList$1.prototype.toggle = function(name, force) {
  1080. if ('undefined' !== typeof force) {
  1081. if (force !== this.list.toggle(name, force)) {
  1082. this.list.toggle(name); // toggle again to correct
  1083. }
  1084. } else {
  1085. this.list.toggle(name);
  1086. }
  1087. return this;
  1088. };
  1089. /**
  1090. * Return an array of classes.
  1091. *
  1092. * @return {Array}
  1093. * @api public
  1094. */
  1095. ClassList$1.prototype.array = function() {
  1096. return Array.from(this.list);
  1097. };
  1098. /**
  1099. * Check if class `name` is present.
  1100. *
  1101. * @param {String} name
  1102. * @return {ClassList}
  1103. * @api public
  1104. */
  1105. ClassList$1.prototype.has =
  1106. ClassList$1.prototype.contains = function(name) {
  1107. return this.list.contains(name);
  1108. };
  1109. function remove$2(element) {
  1110. var parent = element.parentNode;
  1111. if (parent) {
  1112. parent.removeChild(element);
  1113. }
  1114. return element;
  1115. }
  1116. /**
  1117. * Clear utility
  1118. */
  1119. /**
  1120. * Removes all children from the given element
  1121. *
  1122. * @param {DOMElement} element
  1123. * @return {DOMElement} the element (for chaining)
  1124. */
  1125. function clear$1(element) {
  1126. var child;
  1127. while ((child = element.firstChild)) {
  1128. remove$2(child);
  1129. }
  1130. return element;
  1131. }
  1132. var ns = {
  1133. svg: 'http://www.w3.org/2000/svg'
  1134. };
  1135. /**
  1136. * DOM parsing utility
  1137. */
  1138. var SVG_START = '<svg xmlns="' + ns.svg + '"';
  1139. function parse$1(svg) {
  1140. var unwrap = false;
  1141. // ensure we import a valid svg document
  1142. if (svg.substring(0, 4) === '<svg') {
  1143. if (svg.indexOf(ns.svg) === -1) {
  1144. svg = SVG_START + svg.substring(4);
  1145. }
  1146. } else {
  1147. // namespace svg
  1148. svg = SVG_START + '>' + svg + '</svg>';
  1149. unwrap = true;
  1150. }
  1151. var parsed = parseDocument(svg);
  1152. if (!unwrap) {
  1153. return parsed;
  1154. }
  1155. var fragment = document.createDocumentFragment();
  1156. var parent = parsed.firstChild;
  1157. while (parent.firstChild) {
  1158. fragment.appendChild(parent.firstChild);
  1159. }
  1160. return fragment;
  1161. }
  1162. function parseDocument(svg) {
  1163. var parser;
  1164. // parse
  1165. parser = new DOMParser();
  1166. parser.async = false;
  1167. return parser.parseFromString(svg, 'text/xml');
  1168. }
  1169. /**
  1170. * Create utility for SVG elements
  1171. */
  1172. /**
  1173. * Create a specific type from name or SVG markup.
  1174. *
  1175. * @param {String} name the name or markup of the element
  1176. * @param {Object} [attrs] attributes to set on the element
  1177. *
  1178. * @returns {SVGElement}
  1179. */
  1180. function create$1(name, attrs) {
  1181. var element;
  1182. if (name.charAt(0) === '<') {
  1183. element = parse$1(name).firstChild;
  1184. element = document.importNode(element, true);
  1185. } else {
  1186. element = document.createElementNS(ns.svg, name);
  1187. }
  1188. if (attrs) {
  1189. attr$1(element, attrs);
  1190. }
  1191. return element;
  1192. }
  1193. /**
  1194. * Geometry helpers
  1195. */
  1196. // fake node used to instantiate svg geometry elements
  1197. var node = null;
  1198. function getNode() {
  1199. if (node === null) {
  1200. node = create$1('svg');
  1201. }
  1202. return node;
  1203. }
  1204. function extend$1(object, props) {
  1205. var i, k, keys = Object.keys(props);
  1206. for (i = 0; (k = keys[i]); i++) {
  1207. object[k] = props[k];
  1208. }
  1209. return object;
  1210. }
  1211. /**
  1212. * Create matrix via args.
  1213. *
  1214. * @example
  1215. *
  1216. * createMatrix({ a: 1, b: 1 });
  1217. * createMatrix();
  1218. * createMatrix(1, 2, 0, 0, 30, 20);
  1219. *
  1220. * @return {SVGMatrix}
  1221. */
  1222. function createMatrix(a, b, c, d, e, f) {
  1223. var matrix = getNode().createSVGMatrix();
  1224. switch (arguments.length) {
  1225. case 0:
  1226. return matrix;
  1227. case 1:
  1228. return extend$1(matrix, a);
  1229. case 6:
  1230. return extend$1(matrix, {
  1231. a: a,
  1232. b: b,
  1233. c: c,
  1234. d: d,
  1235. e: e,
  1236. f: f
  1237. });
  1238. }
  1239. }
  1240. function createTransform(matrix) {
  1241. if (matrix) {
  1242. return getNode().createSVGTransformFromMatrix(matrix);
  1243. } else {
  1244. return getNode().createSVGTransform();
  1245. }
  1246. }
  1247. /**
  1248. * Serialization util
  1249. */
  1250. var TEXT_ENTITIES = /([&<>]{1})/g;
  1251. var ATTR_ENTITIES = /([\n\r"]{1})/g;
  1252. var ENTITY_REPLACEMENT = {
  1253. '&': '&amp;',
  1254. '<': '&lt;',
  1255. '>': '&gt;',
  1256. '"': '\''
  1257. };
  1258. function escape$1(str, pattern) {
  1259. function replaceFn(match, entity) {
  1260. return ENTITY_REPLACEMENT[entity] || entity;
  1261. }
  1262. return str.replace(pattern, replaceFn);
  1263. }
  1264. function serialize(node, output) {
  1265. var i, len, attrMap, attrNode, childNodes;
  1266. switch (node.nodeType) {
  1267. // TEXT
  1268. case 3:
  1269. // replace special XML characters
  1270. output.push(escape$1(node.textContent, TEXT_ENTITIES));
  1271. break;
  1272. // ELEMENT
  1273. case 1:
  1274. output.push('<', node.tagName);
  1275. if (node.hasAttributes()) {
  1276. attrMap = node.attributes;
  1277. for (i = 0, len = attrMap.length; i < len; ++i) {
  1278. attrNode = attrMap.item(i);
  1279. output.push(' ', attrNode.name, '="', escape$1(attrNode.value, ATTR_ENTITIES), '"');
  1280. }
  1281. }
  1282. if (node.hasChildNodes()) {
  1283. output.push('>');
  1284. childNodes = node.childNodes;
  1285. for (i = 0, len = childNodes.length; i < len; ++i) {
  1286. serialize(childNodes.item(i), output);
  1287. }
  1288. output.push('</', node.tagName, '>');
  1289. } else {
  1290. output.push('/>');
  1291. }
  1292. break;
  1293. // COMMENT
  1294. case 8:
  1295. output.push('<!--', escape$1(node.nodeValue, TEXT_ENTITIES), '-->');
  1296. break;
  1297. // CDATA
  1298. case 4:
  1299. output.push('<![CDATA[', node.nodeValue, ']]>');
  1300. break;
  1301. default:
  1302. throw new Error('unable to handle node ' + node.nodeType);
  1303. }
  1304. return output;
  1305. }
  1306. /**
  1307. * innerHTML like functionality for SVG elements.
  1308. * based on innerSVG (https://code.google.com/p/innersvg)
  1309. */
  1310. function set(element, svg) {
  1311. var parsed = parse$1(svg);
  1312. // clear element contents
  1313. clear$1(element);
  1314. if (!svg) {
  1315. return;
  1316. }
  1317. if (!isFragment(parsed)) {
  1318. // extract <svg> from parsed document
  1319. parsed = parsed.documentElement;
  1320. }
  1321. var nodes = slice$1(parsed.childNodes);
  1322. // import + append each node
  1323. for (var i = 0; i < nodes.length; i++) {
  1324. appendTo(nodes[i], element);
  1325. }
  1326. }
  1327. function get(element) {
  1328. var child = element.firstChild,
  1329. output = [];
  1330. while (child) {
  1331. serialize(child, output);
  1332. child = child.nextSibling;
  1333. }
  1334. return output.join('');
  1335. }
  1336. function isFragment(node) {
  1337. return node.nodeName === '#document-fragment';
  1338. }
  1339. function innerSVG(element, svg) {
  1340. if (svg !== undefined) {
  1341. try {
  1342. set(element, svg);
  1343. } catch (e) {
  1344. throw new Error('error parsing SVG: ' + e.message);
  1345. }
  1346. return element;
  1347. } else {
  1348. return get(element);
  1349. }
  1350. }
  1351. function slice$1(arr) {
  1352. return Array.prototype.slice.call(arr);
  1353. }
  1354. /**
  1355. * transform accessor utility
  1356. */
  1357. function wrapMatrix(transformList, transform) {
  1358. if (transform instanceof SVGMatrix) {
  1359. return transformList.createSVGTransformFromMatrix(transform);
  1360. }
  1361. return transform;
  1362. }
  1363. function setTransforms(transformList, transforms) {
  1364. var i, t;
  1365. transformList.clear();
  1366. for (i = 0; (t = transforms[i]); i++) {
  1367. transformList.appendItem(wrapMatrix(transformList, t));
  1368. }
  1369. }
  1370. /**
  1371. * Get or set the transforms on the given node.
  1372. *
  1373. * @param {SVGElement} node
  1374. * @param {SVGTransform|SVGMatrix|Array<SVGTransform|SVGMatrix>} [transforms]
  1375. *
  1376. * @return {SVGTransform} the consolidated transform
  1377. */
  1378. function transform$1(node, transforms) {
  1379. var transformList = node.transform.baseVal;
  1380. if (transforms) {
  1381. if (!Array.isArray(transforms)) {
  1382. transforms = [ transforms ];
  1383. }
  1384. setTransforms(transformList, transforms);
  1385. }
  1386. return transformList.consolidate();
  1387. }
  1388. /**
  1389. * @typedef {(string|number)[]} Component
  1390. *
  1391. * @typedef {import('../util/Types').Point} Point
  1392. */
  1393. /**
  1394. * @param {Component[] | Component[][]} elements
  1395. *
  1396. * @return {string}
  1397. */
  1398. function componentsToPath(elements) {
  1399. return elements.flat().join(',').replace(/,?([A-z]),?/g, '$1');
  1400. }
  1401. /**
  1402. * @param {Point} point
  1403. *
  1404. * @return {Component[]}
  1405. */
  1406. function move(point) {
  1407. return [ 'M', point.x, point.y ];
  1408. }
  1409. /**
  1410. * @param {Point} point
  1411. *
  1412. * @return {Component[]}
  1413. */
  1414. function lineTo(point) {
  1415. return [ 'L', point.x, point.y ];
  1416. }
  1417. /**
  1418. * @param {Point} p1
  1419. * @param {Point} p2
  1420. * @param {Point} p3
  1421. *
  1422. * @return {Component[]}
  1423. */
  1424. function curveTo(p1, p2, p3) {
  1425. return [ 'C', p1.x, p1.y, p2.x, p2.y, p3.x, p3.y ];
  1426. }
  1427. /**
  1428. * @param {Point[]} waypoints
  1429. * @param {number} [cornerRadius]
  1430. * @return {Component[][]}
  1431. */
  1432. function drawPath(waypoints, cornerRadius) {
  1433. const pointCount = waypoints.length;
  1434. const path = [ move(waypoints[0]) ];
  1435. for (let i = 1; i < pointCount; i++) {
  1436. const pointBefore = waypoints[i - 1];
  1437. const point = waypoints[i];
  1438. const pointAfter = waypoints[i + 1];
  1439. if (!pointAfter || !cornerRadius) {
  1440. path.push(lineTo(point));
  1441. continue;
  1442. }
  1443. const effectiveRadius = Math.min(
  1444. cornerRadius,
  1445. vectorLength(point.x - pointBefore.x, point.y - pointBefore.y),
  1446. vectorLength(pointAfter.x - point.x, pointAfter.y - point.y)
  1447. );
  1448. if (!effectiveRadius) {
  1449. path.push(lineTo(point));
  1450. continue;
  1451. }
  1452. const beforePoint = getPointAtLength(point, pointBefore, effectiveRadius);
  1453. const beforePoint2 = getPointAtLength(point, pointBefore, effectiveRadius * .5);
  1454. const afterPoint = getPointAtLength(point, pointAfter, effectiveRadius);
  1455. const afterPoint2 = getPointAtLength(point, pointAfter, effectiveRadius * .5);
  1456. path.push(lineTo(beforePoint));
  1457. path.push(curveTo(beforePoint2, afterPoint2, afterPoint));
  1458. }
  1459. return path;
  1460. }
  1461. function getPointAtLength(start, end, length) {
  1462. const deltaX = end.x - start.x;
  1463. const deltaY = end.y - start.y;
  1464. const totalLength = vectorLength(deltaX, deltaY);
  1465. const percent = length / totalLength;
  1466. return {
  1467. x: start.x + deltaX * percent,
  1468. y: start.y + deltaY * percent
  1469. };
  1470. }
  1471. function vectorLength(x, y) {
  1472. return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
  1473. }
  1474. /**
  1475. * @param {Point[]} points
  1476. * @param {number|Object} [attrs]
  1477. * @param {number} [radius]
  1478. *
  1479. * @return {SVGElement}
  1480. */
  1481. function createLine(points, attrs, radius) {
  1482. if (isNumber(attrs)) {
  1483. radius = attrs;
  1484. attrs = null;
  1485. }
  1486. if (!attrs) {
  1487. attrs = {};
  1488. }
  1489. const line = create$1('path', attrs);
  1490. if (isNumber(radius)) {
  1491. line.dataset.cornerRadius = String(radius);
  1492. }
  1493. return updateLine(line, points);
  1494. }
  1495. /**
  1496. * @param {SVGElement} gfx
  1497. * @param {Point[]} points
  1498. *
  1499. * @return {SVGElement}
  1500. */
  1501. function updateLine(gfx, points) {
  1502. const cornerRadius = parseInt(gfx.dataset.cornerRadius, 10) || 0;
  1503. attr$1(gfx, {
  1504. d: componentsToPath(drawPath(points, cornerRadius))
  1505. });
  1506. return gfx;
  1507. }
  1508. var black = 'hsl(225, 10%, 15%)';
  1509. var white = 'white';
  1510. // element utils //////////////////////
  1511. /**
  1512. * Checks if eventDefinition of the given element matches with semantic type.
  1513. *
  1514. * @param {ModdleElement} event
  1515. * @param {string} eventDefinitionType
  1516. *
  1517. * @return {boolean}
  1518. */
  1519. function isTypedEvent(event, eventDefinitionType) {
  1520. return some(event.eventDefinitions, function(definition) {
  1521. return definition.$type === eventDefinitionType;
  1522. });
  1523. }
  1524. /**
  1525. * Check if element is a throw event.
  1526. *
  1527. * @param {ModdleElement} event
  1528. *
  1529. * @return {boolean}
  1530. */
  1531. function isThrowEvent(event) {
  1532. return (event.$type === 'bpmn:IntermediateThrowEvent') || (event.$type === 'bpmn:EndEvent');
  1533. }
  1534. /**
  1535. * Check if element is a throw event.
  1536. *
  1537. * @param {ModdleElement} element
  1538. *
  1539. * @return {boolean}
  1540. */
  1541. function isCollection(element) {
  1542. var dataObject = element.dataObjectRef;
  1543. return element.isCollection || (dataObject && dataObject.isCollection);
  1544. }
  1545. // color access //////////////////////
  1546. /**
  1547. * @param {Element} element
  1548. * @param {string} [defaultColor]
  1549. * @param {string} [overrideColor]
  1550. *
  1551. * @return {string}
  1552. */
  1553. function getFillColor(element, defaultColor, overrideColor) {
  1554. var di = getDi(element);
  1555. return overrideColor || di.get('color:background-color') || di.get('bioc:fill') || defaultColor || white;
  1556. }
  1557. /**
  1558. * @param {Element} element
  1559. * @param {string} [defaultColor]
  1560. * @param {string} [overrideColor]
  1561. *
  1562. * @return {string}
  1563. */
  1564. function getStrokeColor(element, defaultColor, overrideColor) {
  1565. var di = getDi(element);
  1566. return overrideColor || di.get('color:border-color') || di.get('bioc:stroke') || defaultColor || black;
  1567. }
  1568. /**
  1569. * @param {Element} element
  1570. * @param {string} [defaultColor]
  1571. * @param {string} [defaultStrokeColor]
  1572. * @param {string} [overrideColor]
  1573. *
  1574. * @return {string}
  1575. */
  1576. function getLabelColor(element, defaultColor, defaultStrokeColor, overrideColor) {
  1577. var di = getDi(element),
  1578. label = di.get('label');
  1579. return overrideColor || (label && label.get('color:color')) || defaultColor ||
  1580. getStrokeColor(element, defaultStrokeColor);
  1581. }
  1582. // cropping path customizations //////////////////////
  1583. /**
  1584. * @param {ShapeLike} shape
  1585. *
  1586. * @return {string} path
  1587. */
  1588. function getCirclePath(shape) {
  1589. var cx = shape.x + shape.width / 2,
  1590. cy = shape.y + shape.height / 2,
  1591. radius = shape.width / 2;
  1592. var circlePath = [
  1593. [ 'M', cx, cy ],
  1594. [ 'm', 0, -radius ],
  1595. [ 'a', radius, radius, 0, 1, 1, 0, 2 * radius ],
  1596. [ 'a', radius, radius, 0, 1, 1, 0, -2 * radius ],
  1597. [ 'z' ]
  1598. ];
  1599. return componentsToPath(circlePath);
  1600. }
  1601. /**
  1602. * @param {ShapeLike} shape
  1603. * @param {number} [borderRadius]
  1604. *
  1605. * @return {string} path
  1606. */
  1607. function getRoundRectPath(shape, borderRadius) {
  1608. var x = shape.x,
  1609. y = shape.y,
  1610. width = shape.width,
  1611. height = shape.height;
  1612. var roundRectPath = [
  1613. [ 'M', x + borderRadius, y ],
  1614. [ 'l', width - borderRadius * 2, 0 ],
  1615. [ 'a', borderRadius, borderRadius, 0, 0, 1, borderRadius, borderRadius ],
  1616. [ 'l', 0, height - borderRadius * 2 ],
  1617. [ 'a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, borderRadius ],
  1618. [ 'l', borderRadius * 2 - width, 0 ],
  1619. [ 'a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, -borderRadius ],
  1620. [ 'l', 0, borderRadius * 2 - height ],
  1621. [ 'a', borderRadius, borderRadius, 0, 0, 1, borderRadius, -borderRadius ],
  1622. [ 'z' ]
  1623. ];
  1624. return componentsToPath(roundRectPath);
  1625. }
  1626. /**
  1627. * @param {ShapeLike} shape
  1628. *
  1629. * @return {string} path
  1630. */
  1631. function getDiamondPath(shape) {
  1632. var width = shape.width,
  1633. height = shape.height,
  1634. x = shape.x,
  1635. y = shape.y,
  1636. halfWidth = width / 2,
  1637. halfHeight = height / 2;
  1638. var diamondPath = [
  1639. [ 'M', x + halfWidth, y ],
  1640. [ 'l', halfWidth, halfHeight ],
  1641. [ 'l', -halfWidth, halfHeight ],
  1642. [ 'l', -halfWidth, -halfHeight ],
  1643. [ 'z' ]
  1644. ];
  1645. return componentsToPath(diamondPath);
  1646. }
  1647. /**
  1648. * @param {ShapeLike} shape
  1649. *
  1650. * @return {string} path
  1651. */
  1652. function getRectPath(shape) {
  1653. var x = shape.x,
  1654. y = shape.y,
  1655. width = shape.width,
  1656. height = shape.height;
  1657. var rectPath = [
  1658. [ 'M', x, y ],
  1659. [ 'l', width, 0 ],
  1660. [ 'l', 0, height ],
  1661. [ 'l', -width, 0 ],
  1662. [ 'z' ]
  1663. ];
  1664. return componentsToPath(rectPath);
  1665. }
  1666. /**
  1667. * Get width and height from element or overrides.
  1668. *
  1669. * @param {Dimensions|Rect|ShapeLike} bounds
  1670. * @param {Object} overrides
  1671. *
  1672. * @returns {Dimensions}
  1673. */
  1674. function getBounds(bounds, overrides = {}) {
  1675. return {
  1676. width: getWidth(bounds, overrides),
  1677. height: getHeight(bounds, overrides)
  1678. };
  1679. }
  1680. /**
  1681. * Get width from element or overrides.
  1682. *
  1683. * @param {Dimensions|Rect|ShapeLike} bounds
  1684. * @param {Object} overrides
  1685. *
  1686. * @returns {number}
  1687. */
  1688. function getWidth(bounds, overrides = {}) {
  1689. return has$1(overrides, 'width') ? overrides.width : bounds.width;
  1690. }
  1691. /**
  1692. * Get height from element or overrides.
  1693. *
  1694. * @param {Dimensions|Rect|ShapeLike} bounds
  1695. * @param {Object} overrides
  1696. *
  1697. * @returns {number}
  1698. */
  1699. function getHeight(bounds, overrides = {}) {
  1700. return has$1(overrides, 'height') ? overrides.height : bounds.height;
  1701. }
  1702. function _mergeNamespaces$1(n, m) {
  1703. m.forEach(function (e) {
  1704. e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
  1705. if (k !== 'default' && !(k in n)) {
  1706. var d = Object.getOwnPropertyDescriptor(e, k);
  1707. Object.defineProperty(n, k, d.get ? d : {
  1708. enumerable: true,
  1709. get: function () { return e[k]; }
  1710. });
  1711. }
  1712. });
  1713. });
  1714. return Object.freeze(n);
  1715. }
  1716. /**
  1717. * Flatten array, one level deep.
  1718. *
  1719. * @param {Array<?>} arr
  1720. *
  1721. * @return {Array<?>}
  1722. */
  1723. const nativeToString = Object.prototype.toString;
  1724. const nativeHasOwnProperty = Object.prototype.hasOwnProperty;
  1725. function isUndefined$1(obj) {
  1726. return obj === undefined;
  1727. }
  1728. function isArray$1(obj) {
  1729. return nativeToString.call(obj) === '[object Array]';
  1730. }
  1731. /**
  1732. * Return true, if target owns a property with the given key.
  1733. *
  1734. * @param {Object} target
  1735. * @param {String} key
  1736. *
  1737. * @return {Boolean}
  1738. */
  1739. function has(target, key) {
  1740. return nativeHasOwnProperty.call(target, key);
  1741. }
  1742. /**
  1743. * Iterate over collection; returning something
  1744. * (non-undefined) will stop iteration.
  1745. *
  1746. * @param {Array|Object} collection
  1747. * @param {Function} iterator
  1748. *
  1749. * @return {Object} return result that stopped the iteration
  1750. */
  1751. function forEach(collection, iterator) {
  1752. let val,
  1753. result;
  1754. if (isUndefined$1(collection)) {
  1755. return;
  1756. }
  1757. const convertKey = isArray$1(collection) ? toNum : identity;
  1758. for (let key in collection) {
  1759. if (has(collection, key)) {
  1760. val = collection[key];
  1761. result = iterator(val, convertKey(key));
  1762. if (result === false) {
  1763. return val;
  1764. }
  1765. }
  1766. }
  1767. }
  1768. function identity(arg) {
  1769. return arg;
  1770. }
  1771. function toNum(arg) {
  1772. return Number(arg);
  1773. }
  1774. /**
  1775. * Assigns style attributes in a style-src compliant way.
  1776. *
  1777. * @param {Element} element
  1778. * @param {...Object} styleSources
  1779. *
  1780. * @return {Element} the element
  1781. */
  1782. function assign(element, ...styleSources) {
  1783. const target = element.style;
  1784. forEach(styleSources, function(style) {
  1785. if (!style) {
  1786. return;
  1787. }
  1788. forEach(style, function(value, key) {
  1789. target[key] = value;
  1790. });
  1791. });
  1792. return element;
  1793. }
  1794. /**
  1795. * Set attribute `name` to `val`, or get attr `name`.
  1796. *
  1797. * @param {Element} el
  1798. * @param {String} name
  1799. * @param {String} [val]
  1800. * @api public
  1801. */
  1802. function attr(el, name, val) {
  1803. // get
  1804. if (arguments.length == 2) {
  1805. return el.getAttribute(name);
  1806. }
  1807. // remove
  1808. if (val === null) {
  1809. return el.removeAttribute(name);
  1810. }
  1811. // set
  1812. el.setAttribute(name, val);
  1813. return el;
  1814. }
  1815. /**
  1816. * Taken from https://github.com/component/classes
  1817. *
  1818. * Without the component bits.
  1819. */
  1820. /**
  1821. * toString reference.
  1822. */
  1823. const toString = Object.prototype.toString;
  1824. /**
  1825. * Wrap `el` in a `ClassList`.
  1826. *
  1827. * @param {Element} el
  1828. * @return {ClassList}
  1829. * @api public
  1830. */
  1831. function classes(el) {
  1832. return new ClassList(el);
  1833. }
  1834. /**
  1835. * Initialize a new ClassList for `el`.
  1836. *
  1837. * @param {Element} el
  1838. * @api private
  1839. */
  1840. function ClassList(el) {
  1841. if (!el || !el.nodeType) {
  1842. throw new Error('A DOM element reference is required');
  1843. }
  1844. this.el = el;
  1845. this.list = el.classList;
  1846. }
  1847. /**
  1848. * Add class `name` if not already present.
  1849. *
  1850. * @param {String} name
  1851. * @return {ClassList}
  1852. * @api public
  1853. */
  1854. ClassList.prototype.add = function(name) {
  1855. this.list.add(name);
  1856. return this;
  1857. };
  1858. /**
  1859. * Remove class `name` when present, or
  1860. * pass a regular expression to remove
  1861. * any which match.
  1862. *
  1863. * @param {String|RegExp} name
  1864. * @return {ClassList}
  1865. * @api public
  1866. */
  1867. ClassList.prototype.remove = function(name) {
  1868. if ('[object RegExp]' == toString.call(name)) {
  1869. return this.removeMatching(name);
  1870. }
  1871. this.list.remove(name);
  1872. return this;
  1873. };
  1874. /**
  1875. * Remove all classes matching `re`.
  1876. *
  1877. * @param {RegExp} re
  1878. * @return {ClassList}
  1879. * @api private
  1880. */
  1881. ClassList.prototype.removeMatching = function(re) {
  1882. const arr = this.array();
  1883. for (let i = 0; i < arr.length; i++) {
  1884. if (re.test(arr[i])) {
  1885. this.remove(arr[i]);
  1886. }
  1887. }
  1888. return this;
  1889. };
  1890. /**
  1891. * Toggle class `name`, can force state via `force`.
  1892. *
  1893. * For browsers that support classList, but do not support `force` yet,
  1894. * the mistake will be detected and corrected.
  1895. *
  1896. * @param {String} name
  1897. * @param {Boolean} force
  1898. * @return {ClassList}
  1899. * @api public
  1900. */
  1901. ClassList.prototype.toggle = function(name, force) {
  1902. if ('undefined' !== typeof force) {
  1903. if (force !== this.list.toggle(name, force)) {
  1904. this.list.toggle(name); // toggle again to correct
  1905. }
  1906. } else {
  1907. this.list.toggle(name);
  1908. }
  1909. return this;
  1910. };
  1911. /**
  1912. * Return an array of classes.
  1913. *
  1914. * @return {Array}
  1915. * @api public
  1916. */
  1917. ClassList.prototype.array = function() {
  1918. return Array.from(this.list);
  1919. };
  1920. /**
  1921. * Check if class `name` is present.
  1922. *
  1923. * @param {String} name
  1924. * @return {ClassList}
  1925. * @api public
  1926. */
  1927. ClassList.prototype.has =
  1928. ClassList.prototype.contains = function(name) {
  1929. return this.list.contains(name);
  1930. };
  1931. /**
  1932. * Remove all children from the given element.
  1933. */
  1934. function clear(el) {
  1935. var c;
  1936. while (el.childNodes.length) {
  1937. c = el.childNodes[0];
  1938. el.removeChild(c);
  1939. }
  1940. return el;
  1941. }
  1942. /**
  1943. * @param { HTMLElement } element
  1944. * @param { String } selector
  1945. *
  1946. * @return { boolean }
  1947. */
  1948. function matches(element, selector) {
  1949. return element && typeof element.matches === 'function' && element.matches(selector);
  1950. }
  1951. /**
  1952. * Closest
  1953. *
  1954. * @param {Element} el
  1955. * @param {String} selector
  1956. * @param {Boolean} checkYourSelf (optional)
  1957. */
  1958. function closest(element, selector, checkYourSelf) {
  1959. var currentElem = checkYourSelf ? element : element.parentNode;
  1960. while (currentElem && currentElem.nodeType !== document.DOCUMENT_NODE &&
  1961. currentElem.nodeType !== document.DOCUMENT_FRAGMENT_NODE) {
  1962. if (matches(currentElem, selector)) {
  1963. return currentElem;
  1964. }
  1965. currentElem = currentElem.parentNode;
  1966. }
  1967. return matches(currentElem, selector) ? currentElem : null;
  1968. }
  1969. var componentEvent = {};
  1970. var bind$1, unbind$1, prefix$6;
  1971. function detect () {
  1972. bind$1 = window.addEventListener ? 'addEventListener' : 'attachEvent';
  1973. unbind$1 = window.removeEventListener ? 'removeEventListener' : 'detachEvent';
  1974. prefix$6 = bind$1 !== 'addEventListener' ? 'on' : '';
  1975. }
  1976. /**
  1977. * Bind `el` event `type` to `fn`.
  1978. *
  1979. * @param {Element} el
  1980. * @param {String} type
  1981. * @param {Function} fn
  1982. * @param {Boolean} capture
  1983. * @return {Function}
  1984. * @api public
  1985. */
  1986. var bind_1 = componentEvent.bind = function(el, type, fn, capture){
  1987. if (!bind$1) detect();
  1988. el[bind$1](prefix$6 + type, fn, capture || false);
  1989. return fn;
  1990. };
  1991. /**
  1992. * Unbind `el` event `type`'s callback `fn`.
  1993. *
  1994. * @param {Element} el
  1995. * @param {String} type
  1996. * @param {Function} fn
  1997. * @param {Boolean} capture
  1998. * @return {Function}
  1999. * @api public
  2000. */
  2001. var unbind_1 = componentEvent.unbind = function(el, type, fn, capture){
  2002. if (!unbind$1) detect();
  2003. el[unbind$1](prefix$6 + type, fn, capture || false);
  2004. return fn;
  2005. };
  2006. var event = /*#__PURE__*/_mergeNamespaces$1({
  2007. __proto__: null,
  2008. bind: bind_1,
  2009. unbind: unbind_1,
  2010. 'default': componentEvent
  2011. }, [componentEvent]);
  2012. /**
  2013. * Module dependencies.
  2014. */
  2015. /**
  2016. * Delegate event `type` to `selector`
  2017. * and invoke `fn(e)`. A callback function
  2018. * is returned which may be passed to `.unbind()`.
  2019. *
  2020. * @param {Element} el
  2021. * @param {String} selector
  2022. * @param {String} type
  2023. * @param {Function} fn
  2024. * @param {Boolean} capture
  2025. * @return {Function}
  2026. * @api public
  2027. */
  2028. // Some events don't bubble, so we want to bind to the capture phase instead
  2029. // when delegating.
  2030. var forceCaptureEvents = [ 'focus', 'blur' ];
  2031. function bind(el, selector, type, fn, capture) {
  2032. if (forceCaptureEvents.indexOf(type) !== -1) {
  2033. capture = true;
  2034. }
  2035. return event.bind(el, type, function(e) {
  2036. var target = e.target || e.srcElement;
  2037. e.delegateTarget = closest(target, selector, true);
  2038. if (e.delegateTarget) {
  2039. fn.call(el, e);
  2040. }
  2041. }, capture);
  2042. }
  2043. /**
  2044. * Unbind event `type`'s callback `fn`.
  2045. *
  2046. * @param {Element} el
  2047. * @param {String} type
  2048. * @param {Function} fn
  2049. * @param {Boolean} capture
  2050. * @api public
  2051. */
  2052. function unbind(el, type, fn, capture) {
  2053. if (forceCaptureEvents.indexOf(type) !== -1) {
  2054. capture = true;
  2055. }
  2056. return event.unbind(el, type, fn, capture);
  2057. }
  2058. var delegate = {
  2059. bind,
  2060. unbind
  2061. };
  2062. /**
  2063. * Expose `parse`.
  2064. */
  2065. var domify = parse;
  2066. /**
  2067. * Tests for browser support.
  2068. */
  2069. var innerHTMLBug = false;
  2070. var bugTestDiv;
  2071. if (typeof document !== 'undefined') {
  2072. bugTestDiv = document.createElement('div');
  2073. // Setup
  2074. bugTestDiv.innerHTML = ' <link/><table></table><a href="/a">a</a><input type="checkbox"/>';
  2075. // Make sure that link elements get serialized correctly by innerHTML
  2076. // This requires a wrapper element in IE
  2077. innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length;
  2078. bugTestDiv = undefined;
  2079. }
  2080. /**
  2081. * Wrap map from jquery.
  2082. */
  2083. var map = {
  2084. legend: [1, '<fieldset>', '</fieldset>'],
  2085. tr: [2, '<table><tbody>', '</tbody></table>'],
  2086. col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
  2087. // for script/link/style tags to work in IE6-8, you have to wrap
  2088. // in a div with a non-whitespace character in front, ha!
  2089. _default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', '']
  2090. };
  2091. map.td =
  2092. map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
  2093. map.option =
  2094. map.optgroup = [1, '<select multiple="multiple">', '</select>'];
  2095. map.thead =
  2096. map.tbody =
  2097. map.colgroup =
  2098. map.caption =
  2099. map.tfoot = [1, '<table>', '</table>'];
  2100. map.polyline =
  2101. map.ellipse =
  2102. map.polygon =
  2103. map.circle =
  2104. map.text =
  2105. map.line =
  2106. map.path =
  2107. map.rect =
  2108. map.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">','</svg>'];
  2109. /**
  2110. * Parse `html` and return a DOM Node instance, which could be a TextNode,
  2111. * HTML DOM Node of some kind (<div> for example), or a DocumentFragment
  2112. * instance, depending on the contents of the `html` string.
  2113. *
  2114. * @param {String} html - HTML string to "domify"
  2115. * @param {Document} doc - The `document` instance to create the Node for
  2116. * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance
  2117. * @api private
  2118. */
  2119. function parse(html, doc) {
  2120. if ('string' != typeof html) throw new TypeError('String expected');
  2121. // default to the global `document` object
  2122. if (!doc) doc = document;
  2123. // tag name
  2124. var m = /<([\w:]+)/.exec(html);
  2125. if (!m) return doc.createTextNode(html);
  2126. html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace
  2127. var tag = m[1];
  2128. // body support
  2129. if (tag == 'body') {
  2130. var el = doc.createElement('html');
  2131. el.innerHTML = html;
  2132. return el.removeChild(el.lastChild);
  2133. }
  2134. // wrap map
  2135. var wrap = Object.prototype.hasOwnProperty.call(map, tag) ? map[tag] : map._default;
  2136. var depth = wrap[0];
  2137. var prefix = wrap[1];
  2138. var suffix = wrap[2];
  2139. var el = doc.createElement('div');
  2140. el.innerHTML = prefix + html + suffix;
  2141. while (depth--) el = el.lastChild;
  2142. // one element
  2143. if (el.firstChild == el.lastChild) {
  2144. return el.removeChild(el.firstChild);
  2145. }
  2146. // several elements
  2147. var fragment = doc.createDocumentFragment();
  2148. while (el.firstChild) {
  2149. fragment.appendChild(el.removeChild(el.firstChild));
  2150. }
  2151. return fragment;
  2152. }
  2153. var domify$1 = domify;
  2154. function query(selector, el) {
  2155. el = el || document;
  2156. return el.querySelector(selector);
  2157. }
  2158. function all(selector, el) {
  2159. el = el || document;
  2160. return el.querySelectorAll(selector);
  2161. }
  2162. function remove$1(el) {
  2163. el.parentNode && el.parentNode.removeChild(el);
  2164. }
  2165. /**
  2166. * @param {SVGElement} gfx
  2167. * @param {number} x
  2168. * @param {number} y
  2169. * @param {number} [angle]
  2170. * @param {number} [amount]
  2171. */
  2172. function transform(gfx, x, y, angle, amount) {
  2173. var translate = createTransform();
  2174. translate.setTranslate(x, y);
  2175. var rotate = createTransform();
  2176. rotate.setRotate(angle || 0, 0, 0);
  2177. var scale = createTransform();
  2178. scale.setScale(amount || 1, amount || 1);
  2179. transform$1(gfx, [ translate, rotate, scale ]);
  2180. }
  2181. /**
  2182. * @param {SVGElement} gfx
  2183. * @param {number} x
  2184. * @param {number} y
  2185. */
  2186. function translate$1(gfx, x, y) {
  2187. var translate = createTransform();
  2188. translate.setTranslate(x, y);
  2189. transform$1(gfx, translate);
  2190. }
  2191. /**
  2192. * @param {SVGElement} gfx
  2193. * @param {number} angle
  2194. */
  2195. function rotate(gfx, angle) {
  2196. var rotate = createTransform();
  2197. rotate.setRotate(angle, 0, 0);
  2198. transform$1(gfx, rotate);
  2199. }
  2200. function createCommonjsModule(fn, module) {
  2201. return module = { exports: {} }, fn(module, module.exports), module.exports;
  2202. }
  2203. var hat_1 = createCommonjsModule(function (module) {
  2204. var hat = module.exports = function (bits, base) {
  2205. if (!base) base = 16;
  2206. if (bits === undefined) bits = 128;
  2207. if (bits <= 0) return '0';
  2208. var digits = Math.log(Math.pow(2, bits)) / Math.log(base);
  2209. for (var i = 2; digits === Infinity; i *= 2) {
  2210. digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i;
  2211. }
  2212. var rem = digits - Math.floor(digits);
  2213. var res = '';
  2214. for (var i = 0; i < Math.floor(digits); i++) {
  2215. var x = Math.floor(Math.random() * base).toString(base);
  2216. res = x + res;
  2217. }
  2218. if (rem) {
  2219. var b = Math.pow(base, rem);
  2220. var x = Math.floor(Math.random() * b).toString(base);
  2221. res = x + res;
  2222. }
  2223. var parsed = parseInt(res, base);
  2224. if (parsed !== Infinity && parsed >= Math.pow(2, bits)) {
  2225. return hat(bits, base)
  2226. }
  2227. else return res;
  2228. };
  2229. hat.rack = function (bits, base, expandBy) {
  2230. var fn = function (data) {
  2231. var iters = 0;
  2232. do {
  2233. if (iters ++ > 10) {
  2234. if (expandBy) bits += expandBy;
  2235. else throw new Error('too many ID collisions, use more bits')
  2236. }
  2237. var id = hat(bits, base);
  2238. } while (Object.hasOwnProperty.call(hats, id));
  2239. hats[id] = data;
  2240. return id;
  2241. };
  2242. var hats = fn.hats = {};
  2243. fn.get = function (id) {
  2244. return fn.hats[id];
  2245. };
  2246. fn.set = function (id, value) {
  2247. fn.hats[id] = value;
  2248. return fn;
  2249. };
  2250. fn.bits = bits || 128;
  2251. fn.base = base || 16;
  2252. return fn;
  2253. };
  2254. });
  2255. /**
  2256. * Create a new id generator / cache instance.
  2257. *
  2258. * You may optionally provide a seed that is used internally.
  2259. *
  2260. * @param {Seed} seed
  2261. */
  2262. function Ids(seed) {
  2263. if (!(this instanceof Ids)) {
  2264. return new Ids(seed);
  2265. }
  2266. seed = seed || [128, 36, 1];
  2267. this._seed = seed.length ? hat_1.rack(seed[0], seed[1], seed[2]) : seed;
  2268. }
  2269. /**
  2270. * Generate a next id.
  2271. *
  2272. * @param {Object} [element] element to bind the id to
  2273. *
  2274. * @return {String} id
  2275. */
  2276. Ids.prototype.next = function (element) {
  2277. return this._seed(element || true);
  2278. };
  2279. /**
  2280. * Generate a next id with a given prefix.
  2281. *
  2282. * @param {Object} [element] element to bind the id to
  2283. *
  2284. * @return {String} id
  2285. */
  2286. Ids.prototype.nextPrefixed = function (prefix, element) {
  2287. var id;
  2288. do {
  2289. id = prefix + this.next(true);
  2290. } while (this.assigned(id));
  2291. // claim {prefix}{random}
  2292. this.claim(id, element);
  2293. // return
  2294. return id;
  2295. };
  2296. /**
  2297. * Manually claim an existing id.
  2298. *
  2299. * @param {String} id
  2300. * @param {String} [element] element the id is claimed by
  2301. */
  2302. Ids.prototype.claim = function (id, element) {
  2303. this._seed.set(id, element || true);
  2304. };
  2305. /**
  2306. * Returns true if the given id has already been assigned.
  2307. *
  2308. * @param {String} id
  2309. * @return {Boolean}
  2310. */
  2311. Ids.prototype.assigned = function (id) {
  2312. return this._seed.get(id) || false;
  2313. };
  2314. /**
  2315. * Unclaim an id.
  2316. *
  2317. * @param {String} id the id to unclaim
  2318. */
  2319. Ids.prototype.unclaim = function (id) {
  2320. delete this._seed.hats[id];
  2321. };
  2322. /**
  2323. * Clear all claimed ids.
  2324. */
  2325. Ids.prototype.clear = function () {
  2326. var hats = this._seed.hats,
  2327. id;
  2328. for (id in hats) {
  2329. this.unclaim(id);
  2330. }
  2331. };
  2332. var rendererIds = new Ids();
  2333. var ELEMENT_LABEL_DISTANCE = 10,
  2334. INNER_OUTER_DIST = 3,
  2335. PARTICIPANT_STROKE_WIDTH = 1.5,
  2336. TASK_BORDER_RADIUS = 10;
  2337. var DEFAULT_OPACITY = 0.95,
  2338. FULL_OPACITY = 1,
  2339. LOW_OPACITY = 0.25;
  2340. /**
  2341. * @typedef { Partial<{
  2342. * defaultFillColor: string,
  2343. * defaultStrokeColor: string,
  2344. * defaultLabelColor: string
  2345. * }> } BpmnRendererConfig
  2346. *
  2347. * @typedef { Partial<{
  2348. * fill: string,
  2349. * stroke: string,
  2350. * width: string,
  2351. * height: string
  2352. * }> } Attrs
  2353. */
  2354. /**
  2355. * @typedef { import('../model/Types').Element } Element
  2356. */
  2357. /**
  2358. * A renderer for BPMN elements
  2359. *
  2360. * @param {BpmnRendererConfig} config
  2361. * @param {import('diagram-js/lib/core/EventBus').default} eventBus
  2362. * @param {import('diagram-js/lib/draw/Styles').default} styles
  2363. * @param {import('./PathMap').default} pathMap
  2364. * @param {import('diagram-js/lib/core/Canvas').default} canvas
  2365. * @param {import('./TextRenderer').default} textRenderer
  2366. * @param {number} [priority]
  2367. */
  2368. function BpmnRenderer(
  2369. config, eventBus, styles, pathMap,
  2370. canvas, textRenderer, priority) {
  2371. BaseRenderer.call(this, eventBus, priority);
  2372. var defaultFillColor = config && config.defaultFillColor,
  2373. defaultStrokeColor = config && config.defaultStrokeColor,
  2374. defaultLabelColor = config && config.defaultLabelColor;
  2375. var rendererId = rendererIds.next();
  2376. var markers = {};
  2377. function shapeStyle(attrs) {
  2378. return styles.computeStyle(attrs, {
  2379. strokeLinecap: 'round',
  2380. strokeLinejoin: 'round',
  2381. stroke: black,
  2382. strokeWidth: 2,
  2383. fill: 'white'
  2384. });
  2385. }
  2386. function lineStyle(attrs) {
  2387. return styles.computeStyle(attrs, [ 'no-fill' ], {
  2388. strokeLinecap: 'round',
  2389. strokeLinejoin: 'round',
  2390. stroke: black,
  2391. strokeWidth: 2
  2392. });
  2393. }
  2394. function addMarker(id, options) {
  2395. var {
  2396. ref = { x: 0, y: 0 },
  2397. scale = 1,
  2398. element
  2399. } = options;
  2400. var marker = create$1('marker', {
  2401. id: id,
  2402. viewBox: '0 0 20 20',
  2403. refX: ref.x,
  2404. refY: ref.y,
  2405. markerWidth: 20 * scale,
  2406. markerHeight: 20 * scale,
  2407. orient: 'auto'
  2408. });
  2409. append(marker, element);
  2410. var defs = query('defs', canvas._svg);
  2411. if (!defs) {
  2412. defs = create$1('defs');
  2413. append(canvas._svg, defs);
  2414. }
  2415. append(defs, marker);
  2416. markers[id] = marker;
  2417. }
  2418. function colorEscape(str) {
  2419. // only allow characters and numbers
  2420. return str.replace(/[^0-9a-zA-Z]+/g, '_');
  2421. }
  2422. function marker(type, fill, stroke) {
  2423. var id = type + '-' + colorEscape(fill) + '-' + colorEscape(stroke) + '-' + rendererId;
  2424. if (!markers[id]) {
  2425. createMarker(id, type, fill, stroke);
  2426. }
  2427. return 'url(#' + id + ')';
  2428. }
  2429. function createMarker(id, type, fill, stroke) {
  2430. if (type === 'sequenceflow-end') {
  2431. var sequenceflowEnd = create$1('path', {
  2432. d: 'M 1 5 L 11 10 L 1 15 Z',
  2433. ...shapeStyle({
  2434. fill: stroke,
  2435. stroke: stroke,
  2436. strokeWidth: 1
  2437. })
  2438. });
  2439. addMarker(id, {
  2440. element: sequenceflowEnd,
  2441. ref: { x: 11, y: 10 },
  2442. scale: 0.5
  2443. });
  2444. }
  2445. if (type === 'messageflow-start') {
  2446. var messageflowStart = create$1('circle', {
  2447. cx: 6,
  2448. cy: 6,
  2449. r: 3.5,
  2450. ...shapeStyle({
  2451. fill,
  2452. stroke: stroke,
  2453. strokeWidth: 1,
  2454. // fix for safari / chrome / firefox bug not correctly
  2455. // resetting stroke dash array
  2456. strokeDasharray: [ 10000, 1 ]
  2457. })
  2458. });
  2459. addMarker(id, {
  2460. element: messageflowStart,
  2461. ref: { x: 6, y: 6 }
  2462. });
  2463. }
  2464. if (type === 'messageflow-end') {
  2465. var messageflowEnd = create$1('path', {
  2466. d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z',
  2467. ...shapeStyle({
  2468. fill,
  2469. stroke: stroke,
  2470. strokeWidth: 1,
  2471. // fix for safari / chrome / firefox bug not correctly
  2472. // resetting stroke dash array
  2473. strokeDasharray: [ 10000, 1 ]
  2474. })
  2475. });
  2476. addMarker(id, {
  2477. element: messageflowEnd,
  2478. ref: { x: 8.5, y: 5 }
  2479. });
  2480. }
  2481. if (type === 'association-start') {
  2482. var associationStart = create$1('path', {
  2483. d: 'M 11 5 L 1 10 L 11 15',
  2484. ...lineStyle({
  2485. fill: 'none',
  2486. stroke,
  2487. strokeWidth: 1.5,
  2488. // fix for safari / chrome / firefox bug not correctly
  2489. // resetting stroke dash array
  2490. strokeDasharray: [ 10000, 1 ]
  2491. })
  2492. });
  2493. addMarker(id, {
  2494. element: associationStart,
  2495. ref: { x: 1, y: 10 },
  2496. scale: 0.5
  2497. });
  2498. }
  2499. if (type === 'association-end') {
  2500. var associationEnd = create$1('path', {
  2501. d: 'M 1 5 L 11 10 L 1 15',
  2502. ...lineStyle({
  2503. fill: 'none',
  2504. stroke,
  2505. strokeWidth: 1.5,
  2506. // fix for safari / chrome / firefox bug not correctly
  2507. // resetting stroke dash array
  2508. strokeDasharray: [ 10000, 1 ]
  2509. })
  2510. });
  2511. addMarker(id, {
  2512. element: associationEnd,
  2513. ref: { x: 11, y: 10 },
  2514. scale: 0.5
  2515. });
  2516. }
  2517. if (type === 'conditional-flow-marker') {
  2518. var conditionalFlowMarker = create$1('path', {
  2519. d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z',
  2520. ...shapeStyle({
  2521. fill,
  2522. stroke: stroke
  2523. })
  2524. });
  2525. addMarker(id, {
  2526. element: conditionalFlowMarker,
  2527. ref: { x: -1, y: 10 },
  2528. scale: 0.5
  2529. });
  2530. }
  2531. if (type === 'conditional-default-flow-marker') {
  2532. var defaultFlowMarker = create$1('path', {
  2533. d: 'M 6 4 L 10 16',
  2534. ...shapeStyle({
  2535. stroke: stroke
  2536. })
  2537. });
  2538. addMarker(id, {
  2539. element: defaultFlowMarker,
  2540. ref: { x: 0, y: 10 },
  2541. scale: 0.5
  2542. });
  2543. }
  2544. }
  2545. function drawCircle(parentGfx, width, height, offset, attrs = {}) {
  2546. if (isObject(offset)) {
  2547. attrs = offset;
  2548. offset = 0;
  2549. }
  2550. offset = offset || 0;
  2551. attrs = shapeStyle(attrs);
  2552. var cx = width / 2,
  2553. cy = height / 2;
  2554. var circle = create$1('circle', {
  2555. cx: cx,
  2556. cy: cy,
  2557. r: Math.round((width + height) / 4 - offset),
  2558. ...attrs
  2559. });
  2560. append(parentGfx, circle);
  2561. return circle;
  2562. }
  2563. function drawRect(parentGfx, width, height, r, offset, attrs) {
  2564. if (isObject(offset)) {
  2565. attrs = offset;
  2566. offset = 0;
  2567. }
  2568. offset = offset || 0;
  2569. attrs = shapeStyle(attrs);
  2570. var rect = create$1('rect', {
  2571. x: offset,
  2572. y: offset,
  2573. width: width - offset * 2,
  2574. height: height - offset * 2,
  2575. rx: r,
  2576. ry: r,
  2577. ...attrs
  2578. });
  2579. append(parentGfx, rect);
  2580. return rect;
  2581. }
  2582. function drawDiamond(parentGfx, width, height, attrs) {
  2583. var x_2 = width / 2;
  2584. var y_2 = height / 2;
  2585. var points = [
  2586. { x: x_2, y: 0 },
  2587. { x: width, y: y_2 },
  2588. { x: x_2, y: height },
  2589. { x: 0, y: y_2 }
  2590. ];
  2591. var pointsString = points.map(function(point) {
  2592. return point.x + ',' + point.y;
  2593. }).join(' ');
  2594. attrs = shapeStyle(attrs);
  2595. var polygon = create$1('polygon', {
  2596. ...attrs,
  2597. points: pointsString
  2598. });
  2599. append(parentGfx, polygon);
  2600. return polygon;
  2601. }
  2602. /**
  2603. * @param {SVGElement} parentGfx
  2604. * @param {Point[]} waypoints
  2605. * @param {any} attrs
  2606. * @param {number} [radius]
  2607. *
  2608. * @return {SVGElement}
  2609. */
  2610. function drawLine(parentGfx, waypoints, attrs, radius) {
  2611. attrs = lineStyle(attrs);
  2612. var line = createLine(waypoints, attrs, radius);
  2613. append(parentGfx, line);
  2614. return line;
  2615. }
  2616. /**
  2617. * @param {SVGElement} parentGfx
  2618. * @param {Point[]} waypoints
  2619. * @param {any} attrs
  2620. *
  2621. * @return {SVGElement}
  2622. */
  2623. function drawConnectionSegments(parentGfx, waypoints, attrs) {
  2624. return drawLine(parentGfx, waypoints, attrs, 5);
  2625. }
  2626. function drawPath(parentGfx, d, attrs) {
  2627. attrs = lineStyle(attrs);
  2628. var path = create$1('path', {
  2629. ...attrs,
  2630. d
  2631. });
  2632. append(parentGfx, path);
  2633. return path;
  2634. }
  2635. function drawMarker(type, parentGfx, path, attrs) {
  2636. return drawPath(parentGfx, path, assign$1({ 'data-marker': type }, attrs));
  2637. }
  2638. function renderer(type) {
  2639. return handlers[type];
  2640. }
  2641. function as(type) {
  2642. return function(parentGfx, element, attrs) {
  2643. return renderer(type)(parentGfx, element, attrs);
  2644. };
  2645. }
  2646. var eventIconRenderers = {
  2647. 'bpmn:MessageEventDefinition': function(parentGfx, element, attrs = {}, isThrowing) {
  2648. var pathData = pathMap.getScaledPath('EVENT_MESSAGE', {
  2649. xScaleFactor: 0.9,
  2650. yScaleFactor: 0.9,
  2651. containerWidth: element.width,
  2652. containerHeight: element.height,
  2653. position: {
  2654. mx: 0.235,
  2655. my: 0.315
  2656. }
  2657. });
  2658. var fill = isThrowing
  2659. ? getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  2660. : getFillColor(element, defaultFillColor, attrs.fill);
  2661. var stroke = isThrowing
  2662. ? getFillColor(element, defaultFillColor, attrs.fill)
  2663. : getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  2664. var messagePath = drawPath(parentGfx, pathData, {
  2665. fill,
  2666. stroke,
  2667. strokeWidth: 1
  2668. });
  2669. return messagePath;
  2670. },
  2671. 'bpmn:TimerEventDefinition': function(parentGfx, element, attrs = {}) {
  2672. var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, {
  2673. fill: getFillColor(element, defaultFillColor, attrs.fill),
  2674. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  2675. strokeWidth: 2
  2676. });
  2677. var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', {
  2678. xScaleFactor: 0.75,
  2679. yScaleFactor: 0.75,
  2680. containerWidth: element.width,
  2681. containerHeight: element.height,
  2682. position: {
  2683. mx: 0.5,
  2684. my: 0.5
  2685. }
  2686. });
  2687. drawPath(parentGfx, pathData, {
  2688. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  2689. strokeWidth: 2
  2690. });
  2691. for (var i = 0; i < 12; i++) {
  2692. var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', {
  2693. xScaleFactor: 0.75,
  2694. yScaleFactor: 0.75,
  2695. containerWidth: element.width,
  2696. containerHeight: element.height,
  2697. position: {
  2698. mx: 0.5,
  2699. my: 0.5
  2700. }
  2701. });
  2702. var width = element.width / 2,
  2703. height = element.height / 2;
  2704. drawPath(parentGfx, linePathData, {
  2705. strokeWidth: 1,
  2706. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  2707. transform: 'rotate(' + (i * 30) + ',' + height + ',' + width + ')'
  2708. });
  2709. }
  2710. return circle;
  2711. },
  2712. 'bpmn:EscalationEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  2713. var pathData = pathMap.getScaledPath('EVENT_ESCALATION', {
  2714. xScaleFactor: 1,
  2715. yScaleFactor: 1,
  2716. containerWidth: event.width,
  2717. containerHeight: event.height,
  2718. position: {
  2719. mx: 0.5,
  2720. my: 0.2
  2721. }
  2722. });
  2723. var fill = isThrowing
  2724. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  2725. : getFillColor(event, defaultFillColor, attrs.fill);
  2726. return drawPath(parentGfx, pathData, {
  2727. fill,
  2728. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  2729. strokeWidth: 1
  2730. });
  2731. },
  2732. 'bpmn:ConditionalEventDefinition': function(parentGfx, event, attrs = {}) {
  2733. var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', {
  2734. xScaleFactor: 1,
  2735. yScaleFactor: 1,
  2736. containerWidth: event.width,
  2737. containerHeight: event.height,
  2738. position: {
  2739. mx: 0.5,
  2740. my: 0.222
  2741. }
  2742. });
  2743. return drawPath(parentGfx, pathData, {
  2744. fill: getFillColor(event, defaultFillColor, attrs.fill),
  2745. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  2746. strokeWidth: 1
  2747. });
  2748. },
  2749. 'bpmn:LinkEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  2750. var pathData = pathMap.getScaledPath('EVENT_LINK', {
  2751. xScaleFactor: 1,
  2752. yScaleFactor: 1,
  2753. containerWidth: event.width,
  2754. containerHeight: event.height,
  2755. position: {
  2756. mx: 0.57,
  2757. my: 0.263
  2758. }
  2759. });
  2760. var fill = isThrowing
  2761. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  2762. : getFillColor(event, defaultFillColor, attrs.fill);
  2763. return drawPath(parentGfx, pathData, {
  2764. fill,
  2765. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  2766. strokeWidth: 1
  2767. });
  2768. },
  2769. 'bpmn:ErrorEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  2770. var pathData = pathMap.getScaledPath('EVENT_ERROR', {
  2771. xScaleFactor: 1.1,
  2772. yScaleFactor: 1.1,
  2773. containerWidth: event.width,
  2774. containerHeight: event.height,
  2775. position: {
  2776. mx: 0.2,
  2777. my: 0.722
  2778. }
  2779. });
  2780. var fill = isThrowing
  2781. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  2782. : getFillColor(event, defaultFillColor, attrs.fill);
  2783. return drawPath(parentGfx, pathData, {
  2784. fill,
  2785. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  2786. strokeWidth: 1
  2787. });
  2788. },
  2789. 'bpmn:CancelEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  2790. var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', {
  2791. xScaleFactor: 1.0,
  2792. yScaleFactor: 1.0,
  2793. containerWidth: event.width,
  2794. containerHeight: event.height,
  2795. position: {
  2796. mx: 0.638,
  2797. my: -0.055
  2798. }
  2799. });
  2800. var fill = isThrowing ? getStrokeColor(event, defaultStrokeColor, attrs.stroke) : 'none';
  2801. var path = drawPath(parentGfx, pathData, {
  2802. fill,
  2803. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  2804. strokeWidth: 1
  2805. });
  2806. rotate(path, 45);
  2807. return path;
  2808. },
  2809. 'bpmn:CompensateEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  2810. var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', {
  2811. xScaleFactor: 1,
  2812. yScaleFactor: 1,
  2813. containerWidth: event.width,
  2814. containerHeight: event.height,
  2815. position: {
  2816. mx: 0.22,
  2817. my: 0.5
  2818. }
  2819. });
  2820. var fill = isThrowing
  2821. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  2822. : getFillColor(event, defaultFillColor, attrs.fill);
  2823. return drawPath(parentGfx, pathData, {
  2824. fill,
  2825. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  2826. strokeWidth: 1
  2827. });
  2828. },
  2829. 'bpmn:SignalEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  2830. var pathData = pathMap.getScaledPath('EVENT_SIGNAL', {
  2831. xScaleFactor: 0.9,
  2832. yScaleFactor: 0.9,
  2833. containerWidth: event.width,
  2834. containerHeight: event.height,
  2835. position: {
  2836. mx: 0.5,
  2837. my: 0.2
  2838. }
  2839. });
  2840. var fill = isThrowing
  2841. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  2842. : getFillColor(event, defaultFillColor, attrs.fill);
  2843. return drawPath(parentGfx, pathData, {
  2844. strokeWidth: 1,
  2845. fill,
  2846. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  2847. });
  2848. },
  2849. 'bpmn:MultipleEventDefinition': function(parentGfx, event, attrs = {}, isThrowing) {
  2850. var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', {
  2851. xScaleFactor: 1.1,
  2852. yScaleFactor: 1.1,
  2853. containerWidth: event.width,
  2854. containerHeight: event.height,
  2855. position: {
  2856. mx: 0.222,
  2857. my: 0.36
  2858. }
  2859. });
  2860. var fill = isThrowing
  2861. ? getStrokeColor(event, defaultStrokeColor, attrs.stroke)
  2862. : getFillColor(event, defaultFillColor, attrs.fill);
  2863. return drawPath(parentGfx, pathData, {
  2864. fill,
  2865. strokeWidth: 1
  2866. });
  2867. },
  2868. 'bpmn:ParallelMultipleEventDefinition': function(parentGfx, event, attrs = {}) {
  2869. var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', {
  2870. xScaleFactor: 1.2,
  2871. yScaleFactor: 1.2,
  2872. containerWidth: event.width,
  2873. containerHeight: event.height,
  2874. position: {
  2875. mx: 0.458,
  2876. my: 0.194
  2877. }
  2878. });
  2879. return drawPath(parentGfx, pathData, {
  2880. fill: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  2881. stroke: getStrokeColor(event, defaultStrokeColor, attrs.stroke),
  2882. strokeWidth: 1
  2883. });
  2884. },
  2885. 'bpmn:TerminateEventDefinition': function(parentGfx, element, attrs = {}) {
  2886. var circle = drawCircle(parentGfx, element.width, element.height, 8, {
  2887. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  2888. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  2889. strokeWidth: 4
  2890. });
  2891. return circle;
  2892. }
  2893. };
  2894. function renderEventIcon(element, parentGfx, attrs = {}) {
  2895. var semantic = getBusinessObject(element),
  2896. isThrowing = isThrowEvent(semantic);
  2897. if (semantic.get('eventDefinitions') && semantic.get('eventDefinitions').length > 1) {
  2898. if (semantic.get('parallelMultiple')) {
  2899. return eventIconRenderers[ 'bpmn:ParallelMultipleEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2900. }
  2901. else {
  2902. return eventIconRenderers[ 'bpmn:MultipleEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2903. }
  2904. }
  2905. if (isTypedEvent(semantic, 'bpmn:MessageEventDefinition')) {
  2906. return eventIconRenderers[ 'bpmn:MessageEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2907. }
  2908. if (isTypedEvent(semantic, 'bpmn:TimerEventDefinition')) {
  2909. return eventIconRenderers[ 'bpmn:TimerEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2910. }
  2911. if (isTypedEvent(semantic, 'bpmn:ConditionalEventDefinition')) {
  2912. return eventIconRenderers[ 'bpmn:ConditionalEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2913. }
  2914. if (isTypedEvent(semantic, 'bpmn:SignalEventDefinition')) {
  2915. return eventIconRenderers[ 'bpmn:SignalEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2916. }
  2917. if (isTypedEvent(semantic, 'bpmn:EscalationEventDefinition')) {
  2918. return eventIconRenderers[ 'bpmn:EscalationEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2919. }
  2920. if (isTypedEvent(semantic, 'bpmn:LinkEventDefinition')) {
  2921. return eventIconRenderers[ 'bpmn:LinkEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2922. }
  2923. if (isTypedEvent(semantic, 'bpmn:ErrorEventDefinition')) {
  2924. return eventIconRenderers[ 'bpmn:ErrorEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2925. }
  2926. if (isTypedEvent(semantic, 'bpmn:CancelEventDefinition')) {
  2927. return eventIconRenderers[ 'bpmn:CancelEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2928. }
  2929. if (isTypedEvent(semantic, 'bpmn:CompensateEventDefinition')) {
  2930. return eventIconRenderers[ 'bpmn:CompensateEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2931. }
  2932. if (isTypedEvent(semantic, 'bpmn:TerminateEventDefinition')) {
  2933. return eventIconRenderers[ 'bpmn:TerminateEventDefinition' ](parentGfx, element, attrs, isThrowing);
  2934. }
  2935. return null;
  2936. }
  2937. var taskMarkerRenderers = {
  2938. 'ParticipantMultiplicityMarker': function(parentGfx, element, attrs = {}) {
  2939. var width = getWidth(element, attrs),
  2940. height = getHeight(element, attrs);
  2941. var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
  2942. xScaleFactor: 1,
  2943. yScaleFactor: 1,
  2944. containerWidth: width,
  2945. containerHeight: height,
  2946. position: {
  2947. mx: ((width / 2 - 6) / width),
  2948. my: (height - 15) / height
  2949. }
  2950. });
  2951. drawMarker('participant-multiplicity', parentGfx, markerPath, {
  2952. strokeWidth: 2,
  2953. fill: getFillColor(element, defaultFillColor, attrs.fill),
  2954. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  2955. });
  2956. },
  2957. 'SubProcessMarker': function(parentGfx, element, attrs = {}) {
  2958. var markerRect = drawRect(parentGfx, 14, 14, 0, {
  2959. strokeWidth: 1,
  2960. fill: getFillColor(element, defaultFillColor, attrs.fill),
  2961. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  2962. });
  2963. translate$1(markerRect, element.width / 2 - 7.5, element.height - 20);
  2964. var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', {
  2965. xScaleFactor: 1.5,
  2966. yScaleFactor: 1.5,
  2967. containerWidth: element.width,
  2968. containerHeight: element.height,
  2969. position: {
  2970. mx: (element.width / 2 - 7.5) / element.width,
  2971. my: (element.height - 20) / element.height
  2972. }
  2973. });
  2974. drawMarker('sub-process', parentGfx, markerPath, {
  2975. fill: getFillColor(element, defaultFillColor, attrs.fill),
  2976. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  2977. });
  2978. },
  2979. 'ParallelMarker': function(parentGfx, element, attrs) {
  2980. var width = getWidth(element, attrs),
  2981. height = getHeight(element, attrs);
  2982. var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', {
  2983. xScaleFactor: 1,
  2984. yScaleFactor: 1,
  2985. containerWidth: width,
  2986. containerHeight: height,
  2987. position: {
  2988. mx: ((width / 2 + attrs.parallel) / width),
  2989. my: (height - 20) / height
  2990. }
  2991. });
  2992. drawMarker('parallel', parentGfx, markerPath, {
  2993. fill: getFillColor(element, defaultFillColor, attrs.fill),
  2994. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  2995. });
  2996. },
  2997. 'SequentialMarker': function(parentGfx, element, attrs) {
  2998. var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', {
  2999. xScaleFactor: 1,
  3000. yScaleFactor: 1,
  3001. containerWidth: element.width,
  3002. containerHeight: element.height,
  3003. position: {
  3004. mx: ((element.width / 2 + attrs.seq) / element.width),
  3005. my: (element.height - 19) / element.height
  3006. }
  3007. });
  3008. drawMarker('sequential', parentGfx, markerPath, {
  3009. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3010. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  3011. });
  3012. },
  3013. 'CompensationMarker': function(parentGfx, element, attrs) {
  3014. var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', {
  3015. xScaleFactor: 1,
  3016. yScaleFactor: 1,
  3017. containerWidth: element.width,
  3018. containerHeight: element.height,
  3019. position: {
  3020. mx: ((element.width / 2 + attrs.compensation) / element.width),
  3021. my: (element.height - 13) / element.height
  3022. }
  3023. });
  3024. drawMarker('compensation', parentGfx, markerMath, {
  3025. strokeWidth: 1,
  3026. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3027. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  3028. });
  3029. },
  3030. 'LoopMarker': function(parentGfx, element, attrs) {
  3031. var width = getWidth(element, attrs),
  3032. height = getHeight(element, attrs);
  3033. var markerPath = pathMap.getScaledPath('MARKER_LOOP', {
  3034. xScaleFactor: 1,
  3035. yScaleFactor: 1,
  3036. containerWidth: width,
  3037. containerHeight: height,
  3038. position: {
  3039. mx: ((width / 2 + attrs.loop) / width),
  3040. my: (height - 7) / height
  3041. }
  3042. });
  3043. drawMarker('loop', parentGfx, markerPath, {
  3044. strokeWidth: 1.5,
  3045. fill: 'none',
  3046. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3047. strokeMiterlimit: 0.5
  3048. });
  3049. },
  3050. 'AdhocMarker': function(parentGfx, element, attrs) {
  3051. var width = getWidth(element, attrs),
  3052. height = getHeight(element, attrs);
  3053. var markerPath = pathMap.getScaledPath('MARKER_ADHOC', {
  3054. xScaleFactor: 1,
  3055. yScaleFactor: 1,
  3056. containerWidth: width,
  3057. containerHeight: height,
  3058. position: {
  3059. mx: ((width / 2 + attrs.adhoc) / width),
  3060. my: (height - 15) / height
  3061. }
  3062. });
  3063. drawMarker('adhoc', parentGfx, markerPath, {
  3064. strokeWidth: 1,
  3065. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3066. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  3067. });
  3068. }
  3069. };
  3070. function renderTaskMarker(type, parentGfx, element, attrs) {
  3071. taskMarkerRenderers[ type ](parentGfx, element, attrs);
  3072. }
  3073. function renderTaskMarkers(parentGfx, element, taskMarkers, attrs = {}) {
  3074. attrs = {
  3075. fill: attrs.fill,
  3076. stroke: attrs.stroke,
  3077. width: getWidth(element, attrs),
  3078. height: getHeight(element, attrs)
  3079. };
  3080. var semantic = getBusinessObject(element);
  3081. var subprocess = taskMarkers && taskMarkers.includes('SubProcessMarker');
  3082. if (subprocess) {
  3083. attrs = {
  3084. ...attrs,
  3085. seq: -21,
  3086. parallel: -22,
  3087. compensation: -42,
  3088. loop: -18,
  3089. adhoc: 10
  3090. };
  3091. } else {
  3092. attrs = {
  3093. ...attrs,
  3094. seq: -5,
  3095. parallel: -6,
  3096. compensation: -27,
  3097. loop: 0,
  3098. adhoc: 10
  3099. };
  3100. }
  3101. forEach$1(taskMarkers, function(marker) {
  3102. renderTaskMarker(marker, parentGfx, element, attrs);
  3103. });
  3104. if (semantic.get('isForCompensation')) {
  3105. renderTaskMarker('CompensationMarker', parentGfx, element, attrs);
  3106. }
  3107. if (is$1(semantic, 'bpmn:AdHocSubProcess')) {
  3108. renderTaskMarker('AdhocMarker', parentGfx, element, attrs);
  3109. }
  3110. var loopCharacteristics = semantic.get('loopCharacteristics'),
  3111. isSequential = loopCharacteristics && loopCharacteristics.get('isSequential');
  3112. if (loopCharacteristics) {
  3113. if (isSequential === undefined) {
  3114. renderTaskMarker('LoopMarker', parentGfx, element, attrs);
  3115. }
  3116. if (isSequential === false) {
  3117. renderTaskMarker('ParallelMarker', parentGfx, element, attrs);
  3118. }
  3119. if (isSequential === true) {
  3120. renderTaskMarker('SequentialMarker', parentGfx, element, attrs);
  3121. }
  3122. }
  3123. }
  3124. function renderLabel(parentGfx, label, attrs = {}) {
  3125. attrs = assign$1({
  3126. size: {
  3127. width: 100
  3128. }
  3129. }, attrs);
  3130. var text = textRenderer.createText(label || '', attrs);
  3131. classes$1(text).add('djs-label');
  3132. append(parentGfx, text);
  3133. return text;
  3134. }
  3135. function renderEmbeddedLabel(parentGfx, element, align, attrs = {}) {
  3136. var semantic = getBusinessObject(element);
  3137. var box = getBounds({
  3138. x: element.x,
  3139. y: element.y,
  3140. width: element.width,
  3141. height: element.height
  3142. }, attrs);
  3143. return renderLabel(parentGfx, semantic.name, {
  3144. align,
  3145. box,
  3146. padding: 7,
  3147. style: {
  3148. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  3149. }
  3150. });
  3151. }
  3152. function renderExternalLabel(parentGfx, element, attrs = {}) {
  3153. var box = {
  3154. width: 90,
  3155. height: 30,
  3156. x: element.width / 2 + element.x,
  3157. y: element.height / 2 + element.y
  3158. };
  3159. return renderLabel(parentGfx, getLabel(element), {
  3160. box: box,
  3161. fitBox: true,
  3162. style: assign$1(
  3163. {},
  3164. textRenderer.getExternalStyle(),
  3165. {
  3166. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  3167. }
  3168. )
  3169. });
  3170. }
  3171. function renderLaneLabel(parentGfx, text, element, attrs = {}) {
  3172. var isHorizontalLane = isHorizontal(element);
  3173. var textBox = renderLabel(parentGfx, text, {
  3174. box: {
  3175. height: 30,
  3176. width: isHorizontalLane ? getHeight(element, attrs) : getWidth(element, attrs),
  3177. },
  3178. align: 'center-middle',
  3179. style: {
  3180. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  3181. }
  3182. });
  3183. if (isHorizontalLane) {
  3184. var top = -1 * getHeight(element, attrs);
  3185. transform(textBox, 0, -top, 270);
  3186. }
  3187. }
  3188. function renderActivity(parentGfx, element, attrs = {}) {
  3189. var {
  3190. width,
  3191. height
  3192. } = getBounds(element, attrs);
  3193. return drawRect(parentGfx, width, height, TASK_BORDER_RADIUS, {
  3194. ...attrs,
  3195. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3196. fillOpacity: DEFAULT_OPACITY,
  3197. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  3198. });
  3199. }
  3200. function renderAssociation(parentGfx, element, attrs = {}) {
  3201. var semantic = getBusinessObject(element);
  3202. var fill = getFillColor(element, defaultFillColor, attrs.fill),
  3203. stroke = getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  3204. if (semantic.get('associationDirection') === 'One' ||
  3205. semantic.get('associationDirection') === 'Both') {
  3206. attrs.markerEnd = marker('association-end', fill, stroke);
  3207. }
  3208. if (semantic.get('associationDirection') === 'Both') {
  3209. attrs.markerStart = marker('association-start', fill, stroke);
  3210. }
  3211. attrs = pickAttrs(attrs, [
  3212. 'markerStart',
  3213. 'markerEnd'
  3214. ]);
  3215. return drawConnectionSegments(parentGfx, element.waypoints, {
  3216. ...attrs,
  3217. stroke,
  3218. strokeDasharray: '0, 5'
  3219. });
  3220. }
  3221. function renderDataObject(parentGfx, element, attrs = {}) {
  3222. var fill = getFillColor(element, defaultFillColor, attrs.fill),
  3223. stroke = getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  3224. var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', {
  3225. xScaleFactor: 1,
  3226. yScaleFactor: 1,
  3227. containerWidth: element.width,
  3228. containerHeight: element.height,
  3229. position: {
  3230. mx: 0.474,
  3231. my: 0.296
  3232. }
  3233. });
  3234. var dataObject = drawPath(parentGfx, pathData, {
  3235. fill,
  3236. fillOpacity: DEFAULT_OPACITY,
  3237. stroke
  3238. });
  3239. var semantic = getBusinessObject(element);
  3240. if (isCollection(semantic)) {
  3241. var collectionPathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', {
  3242. xScaleFactor: 1,
  3243. yScaleFactor: 1,
  3244. containerWidth: element.width,
  3245. containerHeight: element.height,
  3246. position: {
  3247. mx: 0.33,
  3248. my: (element.height - 18) / element.height
  3249. }
  3250. });
  3251. drawPath(parentGfx, collectionPathData, {
  3252. strokeWidth: 2,
  3253. fill,
  3254. stroke
  3255. });
  3256. }
  3257. return dataObject;
  3258. }
  3259. function renderEvent(parentGfx, element, attrs = {}) {
  3260. return drawCircle(parentGfx, element.width, element.height, {
  3261. fillOpacity: DEFAULT_OPACITY,
  3262. ...attrs,
  3263. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3264. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  3265. });
  3266. }
  3267. function renderGateway(parentGfx, element, attrs = {}) {
  3268. return drawDiamond(parentGfx, element.width, element.height, {
  3269. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3270. fillOpacity: DEFAULT_OPACITY,
  3271. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  3272. });
  3273. }
  3274. function renderLane(parentGfx, element, attrs = {}) {
  3275. var lane = drawRect(parentGfx, getWidth(element, attrs), getHeight(element, attrs), 0, {
  3276. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3277. fillOpacity: attrs.fillOpacity || DEFAULT_OPACITY,
  3278. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3279. strokeWidth: 1.5
  3280. });
  3281. var semantic = getBusinessObject(element);
  3282. if (is$1(semantic, 'bpmn:Lane')) {
  3283. var text = semantic.get('name');
  3284. renderLaneLabel(parentGfx, text, element, attrs);
  3285. }
  3286. return lane;
  3287. }
  3288. function renderSubProcess(parentGfx, element, attrs = {}) {
  3289. var activity = renderActivity(parentGfx, element, attrs);
  3290. if (isEventSubProcess(element)) {
  3291. attr$1(activity, {
  3292. strokeDasharray: '0, 5.5',
  3293. strokeWidth: 2.5
  3294. });
  3295. }
  3296. var expanded = isExpanded(element);
  3297. renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle', attrs);
  3298. if (expanded) {
  3299. renderTaskMarkers(parentGfx, element, undefined, attrs);
  3300. } else {
  3301. renderTaskMarkers(parentGfx, element, [ 'SubProcessMarker' ], attrs);
  3302. }
  3303. return activity;
  3304. }
  3305. function renderTask(parentGfx, element, attrs = {}) {
  3306. var activity = renderActivity(parentGfx, element, attrs);
  3307. renderEmbeddedLabel(parentGfx, element, 'center-middle', attrs);
  3308. renderTaskMarkers(parentGfx, element, undefined, attrs);
  3309. return activity;
  3310. }
  3311. var handlers = this.handlers = {
  3312. 'bpmn:AdHocSubProcess': function(parentGfx, element, attrs = {}) {
  3313. if (isExpanded(element)) {
  3314. attrs = pickAttrs(attrs, [
  3315. 'fill',
  3316. 'stroke',
  3317. 'width',
  3318. 'height'
  3319. ]);
  3320. } else {
  3321. attrs = pickAttrs(attrs, [
  3322. 'fill',
  3323. 'stroke'
  3324. ]);
  3325. }
  3326. return renderSubProcess(parentGfx, element, attrs);
  3327. },
  3328. 'bpmn:Association': function(parentGfx, element, attrs = {}) {
  3329. attrs = pickAttrs(attrs, [
  3330. 'fill',
  3331. 'stroke'
  3332. ]);
  3333. return renderAssociation(parentGfx, element, attrs);
  3334. },
  3335. 'bpmn:BoundaryEvent': function(parentGfx, element, attrs = {}) {
  3336. var { renderIcon = true } = attrs;
  3337. attrs = pickAttrs(attrs, [
  3338. 'fill',
  3339. 'stroke'
  3340. ]);
  3341. var semantic = getBusinessObject(element),
  3342. cancelActivity = semantic.get('cancelActivity');
  3343. attrs = {
  3344. strokeWidth: 1.5,
  3345. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3346. fillOpacity: FULL_OPACITY,
  3347. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  3348. };
  3349. if (!cancelActivity) {
  3350. attrs.strokeDasharray = '6';
  3351. }
  3352. var event = renderEvent(parentGfx, element, attrs);
  3353. drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, {
  3354. ...attrs,
  3355. fill: 'none'
  3356. });
  3357. if (renderIcon) {
  3358. renderEventIcon(element, parentGfx, attrs);
  3359. }
  3360. return event;
  3361. },
  3362. 'bpmn:BusinessRuleTask': function(parentGfx, element, attrs = {}) {
  3363. attrs = pickAttrs(attrs, [
  3364. 'fill',
  3365. 'stroke'
  3366. ]);
  3367. var task = renderTask(parentGfx, element, attrs);
  3368. var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', {
  3369. abspos: {
  3370. x: 8,
  3371. y: 8
  3372. }
  3373. });
  3374. var businessPath = drawPath(parentGfx, headerData);
  3375. attr$1(businessPath, {
  3376. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3377. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3378. strokeWidth: 1
  3379. });
  3380. var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', {
  3381. abspos: {
  3382. x: 8,
  3383. y: 8
  3384. }
  3385. });
  3386. var businessHeaderPath = drawPath(parentGfx, headerPathData);
  3387. attr$1(businessHeaderPath, {
  3388. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3389. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3390. strokeWidth: 1
  3391. });
  3392. return task;
  3393. },
  3394. 'bpmn:CallActivity': function(parentGfx, element, attrs = {}) {
  3395. attrs = pickAttrs(attrs, [
  3396. 'fill',
  3397. 'stroke'
  3398. ]);
  3399. return renderSubProcess(parentGfx, element, {
  3400. strokeWidth: 5,
  3401. ...attrs
  3402. });
  3403. },
  3404. 'bpmn:ComplexGateway': function(parentGfx, element, attrs = {}) {
  3405. attrs = pickAttrs(attrs, [
  3406. 'fill',
  3407. 'stroke'
  3408. ]);
  3409. var gateway = renderGateway(parentGfx, element, attrs);
  3410. var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', {
  3411. xScaleFactor: 0.5,
  3412. yScaleFactor:0.5,
  3413. containerWidth: element.width,
  3414. containerHeight: element.height,
  3415. position: {
  3416. mx: 0.46,
  3417. my: 0.26
  3418. }
  3419. });
  3420. drawPath(parentGfx, pathData, {
  3421. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3422. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3423. strokeWidth: 1
  3424. });
  3425. return gateway;
  3426. },
  3427. 'bpmn:DataInput': function(parentGfx, element, attrs = {}) {
  3428. attrs = pickAttrs(attrs, [
  3429. 'fill',
  3430. 'stroke'
  3431. ]);
  3432. var arrowPathData = pathMap.getRawPath('DATA_ARROW');
  3433. var dataObject = renderDataObject(parentGfx, element, attrs);
  3434. drawPath(parentGfx, arrowPathData, {
  3435. fill: 'none',
  3436. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3437. strokeWidth: 1
  3438. });
  3439. return dataObject;
  3440. },
  3441. 'bpmn:DataInputAssociation': function(parentGfx, element, attrs = {}) {
  3442. attrs = pickAttrs(attrs, [
  3443. 'fill',
  3444. 'stroke'
  3445. ]);
  3446. return renderAssociation(parentGfx, element, {
  3447. ...attrs,
  3448. markerEnd: marker('association-end', getFillColor(element, defaultFillColor, attrs.fill), getStrokeColor(element, defaultStrokeColor, attrs.stroke))
  3449. });
  3450. },
  3451. 'bpmn:DataObject': function(parentGfx, element, attrs = {}) {
  3452. attrs = pickAttrs(attrs, [
  3453. 'fill',
  3454. 'stroke'
  3455. ]);
  3456. return renderDataObject(parentGfx, element, attrs);
  3457. },
  3458. 'bpmn:DataObjectReference': as('bpmn:DataObject'),
  3459. 'bpmn:DataOutput': function(parentGfx, element, attrs = {}) {
  3460. attrs = pickAttrs(attrs, [
  3461. 'fill',
  3462. 'stroke'
  3463. ]);
  3464. var arrowPathData = pathMap.getRawPath('DATA_ARROW');
  3465. var dataObject = renderDataObject(parentGfx, element, attrs);
  3466. drawPath(parentGfx, arrowPathData, {
  3467. strokeWidth: 1,
  3468. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3469. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  3470. });
  3471. return dataObject;
  3472. },
  3473. 'bpmn:DataOutputAssociation': function(parentGfx, element, attrs = {}) {
  3474. attrs = pickAttrs(attrs, [
  3475. 'fill',
  3476. 'stroke'
  3477. ]);
  3478. return renderAssociation(parentGfx, element, {
  3479. ...attrs,
  3480. markerEnd: marker('association-end', getFillColor(element, defaultFillColor, attrs.fill), getStrokeColor(element, defaultStrokeColor, attrs.stroke))
  3481. });
  3482. },
  3483. 'bpmn:DataStoreReference': function(parentGfx, element, attrs = {}) {
  3484. attrs = pickAttrs(attrs, [
  3485. 'fill',
  3486. 'stroke'
  3487. ]);
  3488. var dataStorePath = pathMap.getScaledPath('DATA_STORE', {
  3489. xScaleFactor: 1,
  3490. yScaleFactor: 1,
  3491. containerWidth: element.width,
  3492. containerHeight: element.height,
  3493. position: {
  3494. mx: 0,
  3495. my: 0.133
  3496. }
  3497. });
  3498. return drawPath(parentGfx, dataStorePath, {
  3499. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3500. fillOpacity: DEFAULT_OPACITY,
  3501. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3502. strokeWidth: 2
  3503. });
  3504. },
  3505. 'bpmn:EndEvent': function(parentGfx, element, attrs = {}) {
  3506. var { renderIcon = true } = attrs;
  3507. attrs = pickAttrs(attrs, [
  3508. 'fill',
  3509. 'stroke'
  3510. ]);
  3511. var event = renderEvent(parentGfx, element, {
  3512. ...attrs,
  3513. strokeWidth: 4
  3514. });
  3515. if (renderIcon) {
  3516. renderEventIcon(element, parentGfx, attrs);
  3517. }
  3518. return event;
  3519. },
  3520. 'bpmn:EventBasedGateway': function(parentGfx, element, attrs = {}) {
  3521. attrs = pickAttrs(attrs, [
  3522. 'fill',
  3523. 'stroke'
  3524. ]);
  3525. var semantic = getBusinessObject(element);
  3526. var diamond = renderGateway(parentGfx, element, attrs);
  3527. drawCircle(parentGfx, element.width, element.height, element.height * 0.20, {
  3528. fill: getFillColor(element, 'none', attrs.fill),
  3529. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3530. strokeWidth: 1
  3531. });
  3532. var type = semantic.get('eventGatewayType'),
  3533. instantiate = !!semantic.get('instantiate');
  3534. function drawEvent() {
  3535. var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', {
  3536. xScaleFactor: 0.18,
  3537. yScaleFactor: 0.18,
  3538. containerWidth: element.width,
  3539. containerHeight: element.height,
  3540. position: {
  3541. mx: 0.36,
  3542. my: 0.44
  3543. }
  3544. });
  3545. drawPath(parentGfx, pathData, {
  3546. fill: 'none',
  3547. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3548. strokeWidth: 2
  3549. });
  3550. }
  3551. if (type === 'Parallel') {
  3552. var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
  3553. xScaleFactor: 0.4,
  3554. yScaleFactor: 0.4,
  3555. containerWidth: element.width,
  3556. containerHeight: element.height,
  3557. position: {
  3558. mx: 0.474,
  3559. my: 0.296
  3560. }
  3561. });
  3562. drawPath(parentGfx, pathData, {
  3563. fill: 'none',
  3564. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3565. strokeWidth: 1
  3566. });
  3567. } else if (type === 'Exclusive') {
  3568. if (!instantiate) {
  3569. drawCircle(parentGfx, element.width, element.height, element.height * 0.26, {
  3570. fill: 'none',
  3571. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3572. strokeWidth: 1
  3573. });
  3574. }
  3575. drawEvent();
  3576. }
  3577. return diamond;
  3578. },
  3579. 'bpmn:ExclusiveGateway': function(parentGfx, element, attrs = {}) {
  3580. attrs = pickAttrs(attrs, [
  3581. 'fill',
  3582. 'stroke'
  3583. ]);
  3584. var gateway = renderGateway(parentGfx, element, attrs);
  3585. var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', {
  3586. xScaleFactor: 0.4,
  3587. yScaleFactor: 0.4,
  3588. containerWidth: element.width,
  3589. containerHeight: element.height,
  3590. position: {
  3591. mx: 0.32,
  3592. my: 0.3
  3593. }
  3594. });
  3595. var di = getDi(element);
  3596. if (di.get('isMarkerVisible')) {
  3597. drawPath(parentGfx, pathData, {
  3598. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3599. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3600. strokeWidth: 1
  3601. });
  3602. }
  3603. return gateway;
  3604. },
  3605. 'bpmn:Gateway': function(parentGfx, element, attrs = {}) {
  3606. attrs = pickAttrs(attrs, [
  3607. 'fill',
  3608. 'stroke'
  3609. ]);
  3610. return renderGateway(parentGfx, element, attrs);
  3611. },
  3612. 'bpmn:Group': function(parentGfx, element, attrs = {}) {
  3613. attrs = pickAttrs(attrs, [
  3614. 'fill',
  3615. 'stroke',
  3616. 'width',
  3617. 'height'
  3618. ]);
  3619. return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, {
  3620. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3621. strokeWidth: 1.5,
  3622. strokeDasharray: '10, 6, 0, 6',
  3623. fill: 'none',
  3624. pointerEvents: 'none',
  3625. width: getWidth(element, attrs),
  3626. height: getHeight(element, attrs)
  3627. });
  3628. },
  3629. 'bpmn:InclusiveGateway': function(parentGfx, element, attrs = {}) {
  3630. attrs = pickAttrs(attrs, [
  3631. 'fill',
  3632. 'stroke'
  3633. ]);
  3634. var gateway = renderGateway(parentGfx, element, attrs);
  3635. drawCircle(parentGfx, element.width, element.height, element.height * 0.24, {
  3636. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3637. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3638. strokeWidth: 2.5
  3639. });
  3640. return gateway;
  3641. },
  3642. 'bpmn:IntermediateEvent': function(parentGfx, element, attrs = {}) {
  3643. var { renderIcon = true } = attrs;
  3644. attrs = pickAttrs(attrs, [
  3645. 'fill',
  3646. 'stroke'
  3647. ]);
  3648. var outer = renderEvent(parentGfx, element, {
  3649. ...attrs,
  3650. strokeWidth: 1.5
  3651. });
  3652. drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, {
  3653. fill: 'none',
  3654. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3655. strokeWidth: 1.5
  3656. });
  3657. if (renderIcon) {
  3658. renderEventIcon(element, parentGfx, attrs);
  3659. }
  3660. return outer;
  3661. },
  3662. 'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'),
  3663. 'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'),
  3664. 'bpmn:Lane': function(parentGfx, element, attrs = {}) {
  3665. attrs = pickAttrs(attrs, [
  3666. 'fill',
  3667. 'stroke',
  3668. 'width',
  3669. 'height'
  3670. ]);
  3671. return renderLane(parentGfx, element, {
  3672. ...attrs,
  3673. fillOpacity: LOW_OPACITY
  3674. });
  3675. },
  3676. 'bpmn:ManualTask': function(parentGfx, element, attrs = {}) {
  3677. attrs = pickAttrs(attrs, [
  3678. 'fill',
  3679. 'stroke'
  3680. ]);
  3681. var task = renderTask(parentGfx, element, attrs);
  3682. var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', {
  3683. abspos: {
  3684. x: 17,
  3685. y: 15
  3686. }
  3687. });
  3688. drawPath(parentGfx, pathData, {
  3689. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3690. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3691. strokeWidth: 0.5
  3692. });
  3693. return task;
  3694. },
  3695. 'bpmn:MessageFlow': function(parentGfx, element, attrs = {}) {
  3696. attrs = pickAttrs(attrs, [
  3697. 'fill',
  3698. 'stroke'
  3699. ]);
  3700. var semantic = getBusinessObject(element),
  3701. di = getDi(element);
  3702. var fill = getFillColor(element, defaultFillColor, attrs.fill),
  3703. stroke = getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  3704. var path = drawConnectionSegments(parentGfx, element.waypoints, {
  3705. markerEnd: marker('messageflow-end', fill, stroke),
  3706. markerStart: marker('messageflow-start', fill, stroke),
  3707. stroke,
  3708. strokeDasharray: '10, 11',
  3709. strokeWidth: 1.5
  3710. });
  3711. if (semantic.get('messageRef')) {
  3712. var midPoint = path.getPointAtLength(path.getTotalLength() / 2);
  3713. var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', {
  3714. abspos: {
  3715. x: midPoint.x,
  3716. y: midPoint.y
  3717. }
  3718. });
  3719. var messageAttrs = {
  3720. strokeWidth: 1
  3721. };
  3722. if (di.get('messageVisibleKind') === 'initiating') {
  3723. messageAttrs.fill = fill;
  3724. messageAttrs.stroke = stroke;
  3725. } else {
  3726. messageAttrs.fill = stroke;
  3727. messageAttrs.stroke = fill;
  3728. }
  3729. var message = drawPath(parentGfx, markerPathData, messageAttrs);
  3730. var messageRef = semantic.get('messageRef'),
  3731. name = messageRef.get('name');
  3732. var label = renderLabel(parentGfx, name, {
  3733. align: 'center-top',
  3734. fitBox: true,
  3735. style: {
  3736. fill: stroke
  3737. }
  3738. });
  3739. var messageBounds = message.getBBox(),
  3740. labelBounds = label.getBBox();
  3741. var translateX = midPoint.x - labelBounds.width / 2,
  3742. translateY = midPoint.y + messageBounds.height / 2 + ELEMENT_LABEL_DISTANCE;
  3743. transform(label, translateX, translateY, 0);
  3744. }
  3745. return path;
  3746. },
  3747. 'bpmn:ParallelGateway': function(parentGfx, element, attrs = {}) {
  3748. attrs = pickAttrs(attrs, [
  3749. 'fill',
  3750. 'stroke'
  3751. ]);
  3752. var diamond = renderGateway(parentGfx, element, attrs);
  3753. var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', {
  3754. xScaleFactor: 0.6,
  3755. yScaleFactor: 0.6,
  3756. containerWidth: element.width,
  3757. containerHeight: element.height,
  3758. position: {
  3759. mx: 0.46,
  3760. my: 0.2
  3761. }
  3762. });
  3763. drawPath(parentGfx, pathData, {
  3764. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3765. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3766. strokeWidth: 1
  3767. });
  3768. return diamond;
  3769. },
  3770. 'bpmn:Participant': function(parentGfx, element, attrs = {}) {
  3771. attrs = pickAttrs(attrs, [
  3772. 'fill',
  3773. 'stroke',
  3774. 'width',
  3775. 'height'
  3776. ]);
  3777. var participant = renderLane(parentGfx, element, attrs);
  3778. var expandedParticipant = isExpanded(element);
  3779. var horizontalParticipant = isHorizontal(element);
  3780. var semantic = getBusinessObject(element),
  3781. name = semantic.get('name');
  3782. if (expandedParticipant) {
  3783. var waypoints = horizontalParticipant ? [
  3784. {
  3785. x: 30,
  3786. y: 0
  3787. },
  3788. {
  3789. x: 30,
  3790. y: getHeight(element, attrs)
  3791. }
  3792. ] : [
  3793. {
  3794. x: 0,
  3795. y: 30
  3796. },
  3797. {
  3798. x: getWidth(element, attrs),
  3799. y: 30
  3800. }
  3801. ];
  3802. drawLine(parentGfx, waypoints, {
  3803. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3804. strokeWidth: PARTICIPANT_STROKE_WIDTH
  3805. });
  3806. renderLaneLabel(parentGfx, name, element, attrs);
  3807. } else {
  3808. var bounds = getBounds(element, attrs);
  3809. if (!horizontalParticipant) {
  3810. bounds.height = getWidth(element, attrs);
  3811. bounds.width = getHeight(element, attrs);
  3812. }
  3813. var textBox = renderLabel(parentGfx, name, {
  3814. box: bounds,
  3815. align: 'center-middle',
  3816. style: {
  3817. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  3818. }
  3819. });
  3820. if (!horizontalParticipant) {
  3821. var top = -1 * getHeight(element, attrs);
  3822. transform(textBox, 0, -top, 270);
  3823. }
  3824. }
  3825. if (semantic.get('participantMultiplicity')) {
  3826. renderTaskMarker('ParticipantMultiplicityMarker', parentGfx, element, attrs);
  3827. }
  3828. return participant;
  3829. },
  3830. 'bpmn:ReceiveTask' : function(parentGfx, element, attrs = {}) {
  3831. attrs = pickAttrs(attrs, [
  3832. 'fill',
  3833. 'stroke'
  3834. ]);
  3835. var semantic = getBusinessObject(element);
  3836. var task = renderTask(parentGfx, element, attrs);
  3837. var pathData;
  3838. if (semantic.get('instantiate')) {
  3839. drawCircle(parentGfx, 28, 28, 20 * 0.22, {
  3840. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3841. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3842. strokeWidth: 1
  3843. });
  3844. pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', {
  3845. abspos: {
  3846. x: 7.77,
  3847. y: 9.52
  3848. }
  3849. });
  3850. } else {
  3851. pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
  3852. xScaleFactor: 0.9,
  3853. yScaleFactor: 0.9,
  3854. containerWidth: 21,
  3855. containerHeight: 14,
  3856. position: {
  3857. mx: 0.3,
  3858. my: 0.4
  3859. }
  3860. });
  3861. }
  3862. drawPath(parentGfx, pathData, {
  3863. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3864. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3865. strokeWidth: 1
  3866. });
  3867. return task;
  3868. },
  3869. 'bpmn:ScriptTask': function(parentGfx, element, attrs = {}) {
  3870. attrs = pickAttrs(attrs, [
  3871. 'fill',
  3872. 'stroke'
  3873. ]);
  3874. var task = renderTask(parentGfx, element, attrs);
  3875. var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', {
  3876. abspos: {
  3877. x: 15,
  3878. y: 20
  3879. }
  3880. });
  3881. drawPath(parentGfx, pathData, {
  3882. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3883. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3884. strokeWidth: 1
  3885. });
  3886. return task;
  3887. },
  3888. 'bpmn:SendTask': function(parentGfx, element, attrs = {}) {
  3889. attrs = pickAttrs(attrs, [
  3890. 'fill',
  3891. 'stroke'
  3892. ]);
  3893. var task = renderTask(parentGfx, element, attrs);
  3894. var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', {
  3895. xScaleFactor: 1,
  3896. yScaleFactor: 1,
  3897. containerWidth: 21,
  3898. containerHeight: 14,
  3899. position: {
  3900. mx: 0.285,
  3901. my: 0.357
  3902. }
  3903. });
  3904. drawPath(parentGfx, pathData, {
  3905. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3906. stroke: getFillColor(element, defaultFillColor, attrs.fill),
  3907. strokeWidth: 1
  3908. });
  3909. return task;
  3910. },
  3911. 'bpmn:SequenceFlow': function(parentGfx, element, attrs = {}) {
  3912. attrs = pickAttrs(attrs, [
  3913. 'fill',
  3914. 'stroke'
  3915. ]);
  3916. var fill = getFillColor(element, defaultFillColor, attrs.fill),
  3917. stroke = getStrokeColor(element, defaultStrokeColor, attrs.stroke);
  3918. var connection = drawConnectionSegments(parentGfx, element.waypoints, {
  3919. markerEnd: marker('sequenceflow-end', fill, stroke),
  3920. stroke
  3921. });
  3922. var semantic = getBusinessObject(element);
  3923. var { source } = element;
  3924. if (source) {
  3925. var sourceSemantic = getBusinessObject(source);
  3926. // conditional flow marker
  3927. if (semantic.get('conditionExpression') && is$1(sourceSemantic, 'bpmn:Activity')) {
  3928. attr$1(connection, {
  3929. markerStart: marker('conditional-flow-marker', fill, stroke)
  3930. });
  3931. }
  3932. // default marker
  3933. if (sourceSemantic.get('default') && (is$1(sourceSemantic, 'bpmn:Gateway') || is$1(sourceSemantic, 'bpmn:Activity')) &&
  3934. sourceSemantic.get('default') === semantic) {
  3935. attr$1(connection, {
  3936. markerStart: marker('conditional-default-flow-marker', fill, stroke)
  3937. });
  3938. }
  3939. }
  3940. return connection;
  3941. },
  3942. 'bpmn:ServiceTask': function(parentGfx, element, attrs = {}) {
  3943. attrs = pickAttrs(attrs, [
  3944. 'fill',
  3945. 'stroke'
  3946. ]);
  3947. var task = renderTask(parentGfx, element, attrs);
  3948. drawCircle(parentGfx, 10, 10, {
  3949. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3950. stroke: 'none',
  3951. transform: 'translate(6, 6)'
  3952. });
  3953. var pathDataService1 = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
  3954. abspos: {
  3955. x: 12,
  3956. y: 18
  3957. }
  3958. });
  3959. drawPath(parentGfx, pathDataService1, {
  3960. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3961. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3962. strokeWidth: 1
  3963. });
  3964. drawCircle(parentGfx, 10, 10, {
  3965. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3966. stroke: 'none',
  3967. transform: 'translate(11, 10)'
  3968. });
  3969. var pathDataService2 = pathMap.getScaledPath('TASK_TYPE_SERVICE', {
  3970. abspos: {
  3971. x: 17,
  3972. y: 22
  3973. }
  3974. });
  3975. drawPath(parentGfx, pathDataService2, {
  3976. fill: getFillColor(element, defaultFillColor, attrs.fill),
  3977. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  3978. strokeWidth: 1
  3979. });
  3980. return task;
  3981. },
  3982. 'bpmn:StartEvent': function(parentGfx, element, attrs = {}) {
  3983. var { renderIcon = true } = attrs;
  3984. attrs = pickAttrs(attrs, [
  3985. 'fill',
  3986. 'stroke'
  3987. ]);
  3988. var semantic = getBusinessObject(element);
  3989. if (!semantic.get('isInterrupting')) {
  3990. attrs = {
  3991. ...attrs,
  3992. strokeDasharray: '6'
  3993. };
  3994. }
  3995. var event = renderEvent(parentGfx, element, attrs);
  3996. if (renderIcon) {
  3997. renderEventIcon(element, parentGfx, attrs);
  3998. }
  3999. return event;
  4000. },
  4001. 'bpmn:SubProcess': function(parentGfx, element, attrs = {}) {
  4002. if (isExpanded(element)) {
  4003. attrs = pickAttrs(attrs, [
  4004. 'fill',
  4005. 'stroke',
  4006. 'width',
  4007. 'height'
  4008. ]);
  4009. } else {
  4010. attrs = pickAttrs(attrs, [
  4011. 'fill',
  4012. 'stroke'
  4013. ]);
  4014. }
  4015. return renderSubProcess(parentGfx, element, attrs);
  4016. },
  4017. 'bpmn:Task': function(parentGfx, element, attrs = {}) {
  4018. attrs = pickAttrs(attrs, [
  4019. 'fill',
  4020. 'stroke'
  4021. ]);
  4022. return renderTask(parentGfx, element, attrs);
  4023. },
  4024. 'bpmn:TextAnnotation': function(parentGfx, element, attrs = {}) {
  4025. attrs = pickAttrs(attrs, [
  4026. 'fill',
  4027. 'stroke',
  4028. 'width',
  4029. 'height'
  4030. ]);
  4031. var {
  4032. width,
  4033. height
  4034. } = getBounds(element, attrs);
  4035. var textElement = drawRect(parentGfx, width, height, 0, 0, {
  4036. fill: 'none',
  4037. stroke: 'none'
  4038. });
  4039. var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
  4040. xScaleFactor: 1,
  4041. yScaleFactor: 1,
  4042. containerWidth: width,
  4043. containerHeight: height,
  4044. position: {
  4045. mx: 0.0,
  4046. my: 0.0
  4047. }
  4048. });
  4049. drawPath(parentGfx, textPathData, {
  4050. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke)
  4051. });
  4052. var semantic = getBusinessObject(element),
  4053. text = semantic.get('text') || '';
  4054. renderLabel(parentGfx, text, {
  4055. align: 'left-top',
  4056. box: getBounds(element, attrs),
  4057. padding: 7,
  4058. style: {
  4059. fill: getLabelColor(element, defaultLabelColor, defaultStrokeColor, attrs.stroke)
  4060. }
  4061. });
  4062. return textElement;
  4063. },
  4064. 'bpmn:Transaction': function(parentGfx, element, attrs = {}) {
  4065. if (isExpanded(element)) {
  4066. attrs = pickAttrs(attrs, [
  4067. 'fill',
  4068. 'stroke',
  4069. 'width',
  4070. 'height'
  4071. ]);
  4072. } else {
  4073. attrs = pickAttrs(attrs, [
  4074. 'fill',
  4075. 'stroke'
  4076. ]);
  4077. }
  4078. var outer = renderSubProcess(parentGfx, element, {
  4079. strokeWidth: 1.5,
  4080. ...attrs
  4081. });
  4082. var innerAttrs = styles.style([ 'no-fill', 'no-events' ], {
  4083. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  4084. strokeWidth: 1.5
  4085. });
  4086. var expanded = isExpanded(element);
  4087. if (!expanded) {
  4088. attrs = {};
  4089. }
  4090. drawRect(
  4091. parentGfx,
  4092. getWidth(element, attrs),
  4093. getHeight(element, attrs),
  4094. TASK_BORDER_RADIUS - INNER_OUTER_DIST,
  4095. INNER_OUTER_DIST,
  4096. innerAttrs
  4097. );
  4098. return outer;
  4099. },
  4100. 'bpmn:UserTask': function(parentGfx, element, attrs = {}) {
  4101. attrs = pickAttrs(attrs, [
  4102. 'fill',
  4103. 'stroke'
  4104. ]);
  4105. var task = renderTask(parentGfx, element, attrs);
  4106. var x = 15;
  4107. var y = 12;
  4108. var pathDataUser1 = pathMap.getScaledPath('TASK_TYPE_USER_1', {
  4109. abspos: {
  4110. x: x,
  4111. y: y
  4112. }
  4113. });
  4114. drawPath(parentGfx, pathDataUser1, {
  4115. fill: getFillColor(element, defaultFillColor, attrs.fill),
  4116. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  4117. strokeWidth: 0.5
  4118. });
  4119. var pathDataUser2 = pathMap.getScaledPath('TASK_TYPE_USER_2', {
  4120. abspos: {
  4121. x: x,
  4122. y: y
  4123. }
  4124. });
  4125. drawPath(parentGfx, pathDataUser2, {
  4126. fill: getFillColor(element, defaultFillColor, attrs.fill),
  4127. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  4128. strokeWidth: 0.5
  4129. });
  4130. var pathDataUser3 = pathMap.getScaledPath('TASK_TYPE_USER_3', {
  4131. abspos: {
  4132. x: x,
  4133. y: y
  4134. }
  4135. });
  4136. drawPath(parentGfx, pathDataUser3, {
  4137. fill: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  4138. stroke: getStrokeColor(element, defaultStrokeColor, attrs.stroke),
  4139. strokeWidth: 0.5
  4140. });
  4141. return task;
  4142. },
  4143. 'label': function(parentGfx, element, attrs = {}) {
  4144. return renderExternalLabel(parentGfx, element, attrs);
  4145. }
  4146. };
  4147. // extension API, use at your own risk
  4148. this._drawPath = drawPath;
  4149. this._renderer = renderer;
  4150. }
  4151. e(BpmnRenderer, BaseRenderer);
  4152. BpmnRenderer.$inject = [
  4153. 'config.bpmnRenderer',
  4154. 'eventBus',
  4155. 'styles',
  4156. 'pathMap',
  4157. 'canvas',
  4158. 'textRenderer'
  4159. ];
  4160. /**
  4161. * @param {Element} element
  4162. *
  4163. * @return {boolean}
  4164. */
  4165. BpmnRenderer.prototype.canRender = function(element) {
  4166. return is$1(element, 'bpmn:BaseElement');
  4167. };
  4168. /**
  4169. * Draw shape into parentGfx.
  4170. *
  4171. * @param {SVGElement} parentGfx
  4172. * @param {Element} element
  4173. * @param {Attrs} [attrs]
  4174. *
  4175. * @return {SVGElement} mainGfx
  4176. */
  4177. BpmnRenderer.prototype.drawShape = function(parentGfx, element, attrs = {}) {
  4178. var { type } = element;
  4179. var handler = this._renderer(type);
  4180. return handler(parentGfx, element, attrs);
  4181. };
  4182. /**
  4183. * Draw connection into parentGfx.
  4184. *
  4185. * @param {SVGElement} parentGfx
  4186. * @param {Element} element
  4187. * @param {Attrs} [attrs]
  4188. *
  4189. * @return {SVGElement} mainGfx
  4190. */
  4191. BpmnRenderer.prototype.drawConnection = function(parentGfx, element, attrs = {}) {
  4192. var { type } = element;
  4193. var handler = this._renderer(type);
  4194. return handler(parentGfx, element, attrs);
  4195. };
  4196. /**
  4197. * Get shape path.
  4198. *
  4199. * @param {Element} element
  4200. *
  4201. * @return {string} path
  4202. */
  4203. BpmnRenderer.prototype.getShapePath = function(element) {
  4204. if (is$1(element, 'bpmn:Event')) {
  4205. return getCirclePath(element);
  4206. }
  4207. if (is$1(element, 'bpmn:Activity')) {
  4208. return getRoundRectPath(element, TASK_BORDER_RADIUS);
  4209. }
  4210. if (is$1(element, 'bpmn:Gateway')) {
  4211. return getDiamondPath(element);
  4212. }
  4213. return getRectPath(element);
  4214. };
  4215. /**
  4216. * Pick attributes if they exist.
  4217. *
  4218. * @param {Object} attrs
  4219. * @param {string[]} keys
  4220. *
  4221. * @returns {Object}
  4222. */
  4223. function pickAttrs(attrs, keys = []) {
  4224. return keys.reduce((pickedAttrs, key) => {
  4225. if (attrs[ key ]) {
  4226. pickedAttrs[ key ] = attrs[ key ];
  4227. }
  4228. return pickedAttrs;
  4229. }, {});
  4230. }
  4231. /**
  4232. * @typedef {import('../util/Types').Dimensions} Dimensions
  4233. *
  4234. * @typedef { {
  4235. * top: number;
  4236. * left: number;
  4237. * right: number;
  4238. * bottom: number;
  4239. * } } Padding
  4240. *
  4241. * @typedef { number | Partial<Padding> } PaddingConfig
  4242. *
  4243. * @typedef { {
  4244. * horizontal: 'center' | 'left';
  4245. * vertical: 'top' | 'center';
  4246. * } } Alignment
  4247. *
  4248. * @typedef { 'center-middle' | 'center-top' } AlignmentConfig
  4249. *
  4250. * @typedef { Partial<{
  4251. * align: AlignmentConfig;
  4252. * style: Record<string, number | string>;
  4253. * padding: PaddingConfig;
  4254. * }> } BaseTextConfig
  4255. *
  4256. * @typedef { BaseTextConfig & Partial<{
  4257. * size: Dimensions;
  4258. * }> } TextConfig
  4259. *
  4260. * @typedef { BaseTextConfig & Partial<{
  4261. * box: Dimensions;
  4262. * fitBox: boolean;
  4263. * }> } TextLayoutConfig
  4264. *
  4265. * @typedef { Dimensions & {
  4266. * text: string;
  4267. * } } LineDescriptor
  4268. */
  4269. var DEFAULT_BOX_PADDING = 0;
  4270. var DEFAULT_LABEL_SIZE = {
  4271. width: 150,
  4272. height: 50
  4273. };
  4274. /**
  4275. * @param {AlignmentConfig} align
  4276. * @return {Alignment}
  4277. */
  4278. function parseAlign(align) {
  4279. var parts = align.split('-');
  4280. return {
  4281. horizontal: parts[0] || 'center',
  4282. vertical: parts[1] || 'top'
  4283. };
  4284. }
  4285. /**
  4286. * @param {PaddingConfig} padding
  4287. *
  4288. * @return {Padding}
  4289. */
  4290. function parsePadding(padding) {
  4291. if (isObject(padding)) {
  4292. return assign$1({ top: 0, left: 0, right: 0, bottom: 0 }, padding);
  4293. } else {
  4294. return {
  4295. top: padding,
  4296. left: padding,
  4297. right: padding,
  4298. bottom: padding
  4299. };
  4300. }
  4301. }
  4302. /**
  4303. * @param {string} text
  4304. * @param {SVGTextElement} fakeText
  4305. *
  4306. * @return {import('../util/Types').Dimensions}
  4307. */
  4308. function getTextBBox(text, fakeText) {
  4309. fakeText.textContent = text;
  4310. var textBBox;
  4311. try {
  4312. var bbox,
  4313. emptyLine = text === '';
  4314. // add dummy text, when line is empty to
  4315. // determine correct height
  4316. fakeText.textContent = emptyLine ? 'dummy' : text;
  4317. textBBox = fakeText.getBBox();
  4318. // take text rendering related horizontal
  4319. // padding into account
  4320. bbox = {
  4321. width: textBBox.width + textBBox.x * 2,
  4322. height: textBBox.height
  4323. };
  4324. if (emptyLine) {
  4325. // correct width
  4326. bbox.width = 0;
  4327. }
  4328. return bbox;
  4329. } catch (e) {
  4330. return { width: 0, height: 0 };
  4331. }
  4332. }
  4333. /**
  4334. * Layout the next line and return the layouted element.
  4335. *
  4336. * Alters the lines passed.
  4337. *
  4338. * @param {string[]} lines
  4339. * @param {number} maxWidth
  4340. * @param {SVGTextElement} fakeText
  4341. *
  4342. * @return {LineDescriptor} the line descriptor
  4343. */
  4344. function layoutNext(lines, maxWidth, fakeText) {
  4345. var originalLine = lines.shift(),
  4346. fitLine = originalLine;
  4347. var textBBox;
  4348. for (;;) {
  4349. textBBox = getTextBBox(fitLine, fakeText);
  4350. textBBox.width = fitLine ? textBBox.width : 0;
  4351. // try to fit
  4352. if (fitLine === ' ' || fitLine === '' || textBBox.width < Math.round(maxWidth) || fitLine.length < 2) {
  4353. return fit(lines, fitLine, originalLine, textBBox);
  4354. }
  4355. fitLine = shortenLine(fitLine, textBBox.width, maxWidth);
  4356. }
  4357. }
  4358. /**
  4359. * @param {string[]} lines
  4360. * @param {string} fitLine
  4361. * @param {string} originalLine
  4362. * @param {Dimensions} textBBox
  4363. *
  4364. * @return {LineDescriptor}
  4365. */
  4366. function fit(lines, fitLine, originalLine, textBBox) {
  4367. if (fitLine.length < originalLine.length) {
  4368. var remainder = originalLine.slice(fitLine.length).trim();
  4369. lines.unshift(remainder);
  4370. }
  4371. return {
  4372. width: textBBox.width,
  4373. height: textBBox.height,
  4374. text: fitLine
  4375. };
  4376. }
  4377. var SOFT_BREAK = '\u00AD';
  4378. /**
  4379. * Shortens a line based on spacing and hyphens.
  4380. * Returns the shortened result on success.
  4381. *
  4382. * @param {string} line
  4383. * @param {number} maxLength the maximum characters of the string
  4384. *
  4385. * @return {string} the shortened string
  4386. */
  4387. function semanticShorten(line, maxLength) {
  4388. var parts = line.split(/(\s|-|\u00AD)/g),
  4389. part,
  4390. shortenedParts = [],
  4391. length = 0;
  4392. // try to shorten via break chars
  4393. if (parts.length > 1) {
  4394. while ((part = parts.shift())) {
  4395. if (part.length + length < maxLength) {
  4396. shortenedParts.push(part);
  4397. length += part.length;
  4398. } else {
  4399. // remove previous part, too if hyphen does not fit anymore
  4400. if (part === '-' || part === SOFT_BREAK) {
  4401. shortenedParts.pop();
  4402. }
  4403. break;
  4404. }
  4405. }
  4406. }
  4407. var last = shortenedParts[shortenedParts.length - 1];
  4408. // translate trailing soft break to actual hyphen
  4409. if (last && last === SOFT_BREAK) {
  4410. shortenedParts[shortenedParts.length - 1] = '-';
  4411. }
  4412. return shortenedParts.join('');
  4413. }
  4414. /**
  4415. * @param {string} line
  4416. * @param {number} width
  4417. * @param {number} maxWidth
  4418. *
  4419. * @return {string}
  4420. */
  4421. function shortenLine(line, width, maxWidth) {
  4422. var length = Math.max(line.length * (maxWidth / width), 1);
  4423. // try to shorten semantically (i.e. based on spaces and hyphens)
  4424. var shortenedLine = semanticShorten(line, length);
  4425. if (!shortenedLine) {
  4426. // force shorten by cutting the long word
  4427. shortenedLine = line.slice(0, Math.max(Math.round(length - 1), 1));
  4428. }
  4429. return shortenedLine;
  4430. }
  4431. /**
  4432. * @return {SVGSVGElement}
  4433. */
  4434. function getHelperSvg() {
  4435. var helperSvg = document.getElementById('helper-svg');
  4436. if (!helperSvg) {
  4437. helperSvg = create$1('svg');
  4438. attr$1(helperSvg, {
  4439. id: 'helper-svg'
  4440. });
  4441. assign(helperSvg, {
  4442. visibility: 'hidden',
  4443. position: 'fixed',
  4444. width: 0,
  4445. height: 0
  4446. });
  4447. document.body.appendChild(helperSvg);
  4448. }
  4449. return helperSvg;
  4450. }
  4451. /**
  4452. * Creates a new label utility
  4453. *
  4454. * @param {TextConfig} config
  4455. */
  4456. function Text(config) {
  4457. this._config = assign$1({}, {
  4458. size: DEFAULT_LABEL_SIZE,
  4459. padding: DEFAULT_BOX_PADDING,
  4460. style: {},
  4461. align: 'center-top'
  4462. }, config || {});
  4463. }
  4464. /**
  4465. * Returns the layouted text as an SVG element.
  4466. *
  4467. * @param {string} text
  4468. * @param {TextLayoutConfig} options
  4469. *
  4470. * @return {SVGElement}
  4471. */
  4472. Text.prototype.createText = function(text, options) {
  4473. return this.layoutText(text, options).element;
  4474. };
  4475. /**
  4476. * Returns a labels layouted dimensions.
  4477. *
  4478. * @param {string} text to layout
  4479. * @param {TextLayoutConfig} options
  4480. *
  4481. * @return {Dimensions}
  4482. */
  4483. Text.prototype.getDimensions = function(text, options) {
  4484. return this.layoutText(text, options).dimensions;
  4485. };
  4486. /**
  4487. * Creates and returns a label and its bounding box.
  4488. *
  4489. * @param {string} text the text to render on the label
  4490. * @param {TextLayoutConfig} options
  4491. *
  4492. * @return { {
  4493. * element: SVGElement,
  4494. * dimensions: Dimensions
  4495. * } }
  4496. */
  4497. Text.prototype.layoutText = function(text, options) {
  4498. var box = assign$1({}, this._config.size, options.box),
  4499. style = assign$1({}, this._config.style, options.style),
  4500. align = parseAlign(options.align || this._config.align),
  4501. padding = parsePadding(options.padding !== undefined ? options.padding : this._config.padding),
  4502. fitBox = options.fitBox || false;
  4503. var lineHeight = getLineHeight(style);
  4504. // we split text by lines and normalize
  4505. // {soft break} + {line break} => { line break }
  4506. var lines = text.split(/\u00AD?\r?\n/),
  4507. layouted = [];
  4508. var maxWidth = box.width - padding.left - padding.right;
  4509. // ensure correct rendering by attaching helper text node to invisible SVG
  4510. var helperText = create$1('text');
  4511. attr$1(helperText, { x: 0, y: 0 });
  4512. attr$1(helperText, style);
  4513. var helperSvg = getHelperSvg();
  4514. append(helperSvg, helperText);
  4515. while (lines.length) {
  4516. layouted.push(layoutNext(lines, maxWidth, helperText));
  4517. }
  4518. if (align.vertical === 'middle') {
  4519. padding.top = padding.bottom = 0;
  4520. }
  4521. var totalHeight = reduce(layouted, function(sum, line, idx) {
  4522. return sum + (lineHeight || line.height);
  4523. }, 0) + padding.top + padding.bottom;
  4524. var maxLineWidth = reduce(layouted, function(sum, line, idx) {
  4525. return line.width > sum ? line.width : sum;
  4526. }, 0);
  4527. // the y position of the next line
  4528. var y = padding.top;
  4529. if (align.vertical === 'middle') {
  4530. y += (box.height - totalHeight) / 2;
  4531. }
  4532. // magic number initial offset
  4533. y -= (lineHeight || layouted[0].height) / 4;
  4534. var textElement = create$1('text');
  4535. attr$1(textElement, style);
  4536. // layout each line taking into account that parent
  4537. // shape might resize to fit text size
  4538. forEach$1(layouted, function(line) {
  4539. var x;
  4540. y += (lineHeight || line.height);
  4541. switch (align.horizontal) {
  4542. case 'left':
  4543. x = padding.left;
  4544. break;
  4545. case 'right':
  4546. x = ((fitBox ? maxLineWidth : maxWidth)
  4547. - padding.right - line.width);
  4548. break;
  4549. default:
  4550. // aka center
  4551. x = Math.max((((fitBox ? maxLineWidth : maxWidth)
  4552. - line.width) / 2 + padding.left), 0);
  4553. }
  4554. var tspan = create$1('tspan');
  4555. attr$1(tspan, { x: x, y: y });
  4556. tspan.textContent = line.text;
  4557. append(textElement, tspan);
  4558. });
  4559. remove$2(helperText);
  4560. var dimensions = {
  4561. width: maxLineWidth,
  4562. height: totalHeight
  4563. };
  4564. return {
  4565. dimensions: dimensions,
  4566. element: textElement
  4567. };
  4568. };
  4569. function getLineHeight(style) {
  4570. if ('fontSize' in style && 'lineHeight' in style) {
  4571. return style.lineHeight * parseInt(style.fontSize, 10);
  4572. }
  4573. }
  4574. var DEFAULT_FONT_SIZE = 12;
  4575. var LINE_HEIGHT_RATIO = 1.2;
  4576. var MIN_TEXT_ANNOTATION_HEIGHT = 30;
  4577. /**
  4578. * @typedef { {
  4579. * fontFamily: string;
  4580. * fontSize: number;
  4581. * fontWeight: string;
  4582. * lineHeight: number;
  4583. * } } TextRendererStyle
  4584. *
  4585. * @typedef { {
  4586. * defaultStyle?: Partial<TextRendererStyle>;
  4587. * externalStyle?: Partial<TextRendererStyle>;
  4588. * } } TextRendererConfig
  4589. *
  4590. * @typedef { import('diagram-js/lib/util/Text').TextLayoutConfig } TextLayoutConfig
  4591. *
  4592. * @typedef { import('diagram-js/lib/util/Types').Rect } Rect
  4593. */
  4594. /**
  4595. * Renders text and computes text bounding boxes.
  4596. *
  4597. * @param {TextRendererConfig} [config]
  4598. */
  4599. function TextRenderer(config) {
  4600. var defaultStyle = assign$1({
  4601. fontFamily: 'Arial, sans-serif',
  4602. fontSize: DEFAULT_FONT_SIZE,
  4603. fontWeight: 'normal',
  4604. lineHeight: LINE_HEIGHT_RATIO
  4605. }, config && config.defaultStyle || {});
  4606. var fontSize = parseInt(defaultStyle.fontSize, 10) - 1;
  4607. var externalStyle = assign$1({}, defaultStyle, {
  4608. fontSize: fontSize
  4609. }, config && config.externalStyle || {});
  4610. var textUtil = new Text({
  4611. style: defaultStyle
  4612. });
  4613. /**
  4614. * Get the new bounds of an externally rendered,
  4615. * layouted label.
  4616. *
  4617. * @param {Rect} bounds
  4618. * @param {string} text
  4619. *
  4620. * @return {Rect}
  4621. */
  4622. this.getExternalLabelBounds = function(bounds, text) {
  4623. var layoutedDimensions = textUtil.getDimensions(text, {
  4624. box: {
  4625. width: 90,
  4626. height: 30
  4627. },
  4628. style: externalStyle
  4629. });
  4630. // resize label shape to fit label text
  4631. return {
  4632. x: Math.round(bounds.x + bounds.width / 2 - layoutedDimensions.width / 2),
  4633. y: Math.round(bounds.y),
  4634. width: Math.ceil(layoutedDimensions.width),
  4635. height: Math.ceil(layoutedDimensions.height)
  4636. };
  4637. };
  4638. /**
  4639. * Get the new bounds of text annotation.
  4640. *
  4641. * @param {Rect} bounds
  4642. * @param {string} text
  4643. *
  4644. * @return {Rect}
  4645. */
  4646. this.getTextAnnotationBounds = function(bounds, text) {
  4647. var layoutedDimensions = textUtil.getDimensions(text, {
  4648. box: bounds,
  4649. style: defaultStyle,
  4650. align: 'left-top',
  4651. padding: 5
  4652. });
  4653. return {
  4654. x: bounds.x,
  4655. y: bounds.y,
  4656. width: bounds.width,
  4657. height: Math.max(MIN_TEXT_ANNOTATION_HEIGHT, Math.round(layoutedDimensions.height))
  4658. };
  4659. };
  4660. /**
  4661. * Create a layouted text element.
  4662. *
  4663. * @param {string} text
  4664. * @param {TextLayoutConfig} [options]
  4665. *
  4666. * @return {SVGElement} rendered text
  4667. */
  4668. this.createText = function(text, options) {
  4669. return textUtil.createText(text, options || {});
  4670. };
  4671. /**
  4672. * Get default text style.
  4673. */
  4674. this.getDefaultStyle = function() {
  4675. return defaultStyle;
  4676. };
  4677. /**
  4678. * Get the external text style.
  4679. */
  4680. this.getExternalStyle = function() {
  4681. return externalStyle;
  4682. };
  4683. }
  4684. TextRenderer.$inject = [
  4685. 'config.textRenderer'
  4686. ];
  4687. /**
  4688. * Map containing SVG paths needed by BpmnRenderer
  4689. */
  4690. function PathMap() {
  4691. /**
  4692. * Contains a map of path elements
  4693. *
  4694. * <h1>Path definition</h1>
  4695. * A parameterized path is defined like this:
  4696. * <pre>
  4697. * 'GATEWAY_PARALLEL': {
  4698. * d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
  4699. '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
  4700. * height: 17.5,
  4701. * width: 17.5,
  4702. * heightElements: [2.5, 7.5],
  4703. * widthElements: [2.5, 7.5]
  4704. * }
  4705. * </pre>
  4706. * <p>It's important to specify a correct <b>height and width</b> for the path as the scaling
  4707. * is based on the ratio between the specified height and width in this object and the
  4708. * height and width that is set as scale target (Note x,y coordinates will be scaled with
  4709. * individual ratios).</p>
  4710. * <p>The '<b>heightElements</b>' and '<b>widthElements</b>' array must contain the values that will be scaled.
  4711. * The scaling is based on the computed ratios.
  4712. * Coordinates on the y axis should be in the <b>heightElement</b>'s array, they will be scaled using
  4713. * the computed ratio coefficient.
  4714. * In the parameterized path the scaled values can be accessed through the 'e' object in {} brackets.
  4715. * <ul>
  4716. * <li>The values for the y axis can be accessed in the path string using {e.y0}, {e.y1}, ....</li>
  4717. * <li>The values for the x axis can be accessed in the path string using {e.x0}, {e.x1}, ....</li>
  4718. * </ul>
  4719. * The numbers x0, x1 respectively y0, y1, ... map to the corresponding array index.
  4720. * </p>
  4721. */
  4722. this.pathMap = {
  4723. 'EVENT_MESSAGE': {
  4724. d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
  4725. height: 36,
  4726. width: 36,
  4727. heightElements: [ 6, 14 ],
  4728. widthElements: [ 10.5, 21 ]
  4729. },
  4730. 'EVENT_SIGNAL': {
  4731. d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z',
  4732. height: 36,
  4733. width: 36,
  4734. heightElements: [ 18 ],
  4735. widthElements: [ 10, 20 ]
  4736. },
  4737. 'EVENT_ESCALATION': {
  4738. d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x0},-{e.y1} l -{e.x0},{e.y1} Z',
  4739. height: 36,
  4740. width: 36,
  4741. heightElements: [ 20, 7 ],
  4742. widthElements: [ 8 ]
  4743. },
  4744. 'EVENT_CONDITIONAL': {
  4745. d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' +
  4746. 'M {e.x2},{e.y3} l {e.x0},0 ' +
  4747. 'M {e.x2},{e.y4} l {e.x0},0 ' +
  4748. 'M {e.x2},{e.y5} l {e.x0},0 ' +
  4749. 'M {e.x2},{e.y6} l {e.x0},0 ' +
  4750. 'M {e.x2},{e.y7} l {e.x0},0 ' +
  4751. 'M {e.x2},{e.y8} l {e.x0},0 ',
  4752. height: 36,
  4753. width: 36,
  4754. heightElements: [ 8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5 ],
  4755. widthElements: [ 10.5, 14.5, 12.5 ]
  4756. },
  4757. 'EVENT_LINK': {
  4758. d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z',
  4759. height: 36,
  4760. width: 36,
  4761. heightElements: [ 4.4375, 6.75, 7.8125 ],
  4762. widthElements: [ 9.84375, 13.5 ]
  4763. },
  4764. 'EVENT_ERROR': {
  4765. d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z',
  4766. height: 36,
  4767. width: 36,
  4768. heightElements: [ 0.023, 8.737, 8.151, 16.564, 10.591, 8.714 ],
  4769. widthElements: [ 0.085, 6.672, 6.97, 4.273, 5.337, 6.636 ]
  4770. },
  4771. 'EVENT_CANCEL_45': {
  4772. d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
  4773. '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
  4774. height: 36,
  4775. width: 36,
  4776. heightElements: [ 4.75, 8.5 ],
  4777. widthElements: [ 4.75, 8.5 ]
  4778. },
  4779. 'EVENT_COMPENSATION': {
  4780. d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x1},-{e.y2} {e.x2},-{e.y3} 0,{e.y1} -{e.x2},-{e.y3} z',
  4781. height: 36,
  4782. width: 36,
  4783. heightElements: [ 6.5, 13, 0.4, 6.1 ],
  4784. widthElements: [ 9, 9.3, 8.7 ]
  4785. },
  4786. 'EVENT_TIMER_WH': {
  4787. d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ',
  4788. height: 36,
  4789. width: 36,
  4790. heightElements: [ 10, 2 ],
  4791. widthElements: [ 3, 7 ]
  4792. },
  4793. 'EVENT_TIMER_LINE': {
  4794. d: 'M {mx},{my} ' +
  4795. 'm {e.x0},{e.y0} l -{e.x1},{e.y1} ',
  4796. height: 36,
  4797. width: 36,
  4798. heightElements: [ 10, 3 ],
  4799. widthElements: [ 0, 0 ]
  4800. },
  4801. 'EVENT_MULTIPLE': {
  4802. d:'m {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z',
  4803. height: 36,
  4804. width: 36,
  4805. heightElements: [ 6.28099, 12.56199 ],
  4806. widthElements: [ 3.1405, 9.42149, 12.56198 ]
  4807. },
  4808. 'EVENT_PARALLEL_MULTIPLE': {
  4809. d:'m {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
  4810. '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
  4811. height: 36,
  4812. width: 36,
  4813. heightElements: [ 2.56228, 7.68683 ],
  4814. widthElements: [ 2.56228, 7.68683 ]
  4815. },
  4816. 'GATEWAY_EXCLUSIVE': {
  4817. d:'m {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' +
  4818. '{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' +
  4819. '{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z',
  4820. height: 17.5,
  4821. width: 17.5,
  4822. heightElements: [ 8.5, 6.5312, -6.5312, -8.5 ],
  4823. widthElements: [ 6.5, -6.5, 3, -3, 5, -5 ]
  4824. },
  4825. 'GATEWAY_PARALLEL': {
  4826. d:'m {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' +
  4827. '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z',
  4828. height: 30,
  4829. width: 30,
  4830. heightElements: [ 5, 12.5 ],
  4831. widthElements: [ 5, 12.5 ]
  4832. },
  4833. 'GATEWAY_EVENT_BASED': {
  4834. d:'m {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z',
  4835. height: 11,
  4836. width: 11,
  4837. heightElements: [ -6, 6, 12, -12 ],
  4838. widthElements: [ 9, -3, -12 ]
  4839. },
  4840. 'GATEWAY_COMPLEX': {
  4841. d:'m {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' +
  4842. '{e.x2},0 -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' +
  4843. '{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' +
  4844. '-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z',
  4845. height: 17.125,
  4846. width: 17.125,
  4847. heightElements: [ 4.875, 3.4375, 2.125, 3 ],
  4848. widthElements: [ 3.4375, 2.125, 4.875, 3 ]
  4849. },
  4850. 'DATA_OBJECT_PATH': {
  4851. d:'m 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0',
  4852. height: 61,
  4853. width: 51,
  4854. heightElements: [ 10, 50, 60 ],
  4855. widthElements: [ 10, 40, 50, 60 ]
  4856. },
  4857. 'DATA_OBJECT_COLLECTION_PATH': {
  4858. d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10',
  4859. height: 10,
  4860. width: 10,
  4861. heightElements: [],
  4862. widthElements: []
  4863. },
  4864. 'DATA_ARROW': {
  4865. d:'m 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z',
  4866. height: 61,
  4867. width: 51,
  4868. heightElements: [],
  4869. widthElements: []
  4870. },
  4871. 'DATA_STORE': {
  4872. d:'m {mx},{my} ' +
  4873. 'l 0,{e.y2} ' +
  4874. 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' +
  4875. 'l 0,-{e.y2} ' +
  4876. 'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' +
  4877. 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' +
  4878. 'm -{e.x2},{e.y0}' +
  4879. 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' +
  4880. 'm -{e.x2},{e.y0}' +
  4881. 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0',
  4882. height: 61,
  4883. width: 61,
  4884. heightElements: [ 7, 10, 45 ],
  4885. widthElements: [ 2, 58, 60 ]
  4886. },
  4887. 'TEXT_ANNOTATION': {
  4888. d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0',
  4889. height: 30,
  4890. width: 10,
  4891. heightElements: [ 30 ],
  4892. widthElements: [ 10 ]
  4893. },
  4894. 'MARKER_SUB_PROCESS': {
  4895. d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0',
  4896. height: 10,
  4897. width: 10,
  4898. heightElements: [],
  4899. widthElements: []
  4900. },
  4901. 'MARKER_PARALLEL': {
  4902. d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10',
  4903. height: 10,
  4904. width: 10,
  4905. heightElements: [],
  4906. widthElements: []
  4907. },
  4908. 'MARKER_SEQUENTIAL': {
  4909. d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0',
  4910. height: 10,
  4911. width: 10,
  4912. heightElements: [],
  4913. widthElements: []
  4914. },
  4915. 'MARKER_COMPENSATION': {
  4916. d: 'm {mx},{my} 7,-5 0,10 z m 7.1,-0.3 6.9,-4.7 0,10 -6.9,-4.7 z',
  4917. height: 10,
  4918. width: 21,
  4919. heightElements: [],
  4920. widthElements: []
  4921. },
  4922. 'MARKER_LOOP': {
  4923. d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' +
  4924. '-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' +
  4925. '0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' +
  4926. 'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902',
  4927. height: 13.9,
  4928. width: 13.7,
  4929. heightElements: [],
  4930. widthElements: []
  4931. },
  4932. 'MARKER_ADHOC': {
  4933. d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' +
  4934. '3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' +
  4935. '1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' +
  4936. '-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' +
  4937. '-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z',
  4938. height: 4,
  4939. width: 15,
  4940. heightElements: [],
  4941. widthElements: []
  4942. },
  4943. 'TASK_TYPE_SEND': {
  4944. d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}',
  4945. height: 14,
  4946. width: 21,
  4947. heightElements: [ 6, 14 ],
  4948. widthElements: [ 10.5, 21 ]
  4949. },
  4950. 'TASK_TYPE_SCRIPT': {
  4951. d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' +
  4952. 'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' +
  4953. 'm -7,-12 l 5,0 ' +
  4954. 'm -4.5,3 l 4.5,0 ' +
  4955. 'm -3,3 l 5,0' +
  4956. 'm -4,3 l 5,0',
  4957. height: 15,
  4958. width: 12.6,
  4959. heightElements: [ 6, 14 ],
  4960. widthElements: [ 10.5, 21 ]
  4961. },
  4962. 'TASK_TYPE_USER_1': {
  4963. d: 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' +
  4964. '-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' +
  4965. '0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' +
  4966. 'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' +
  4967. 'm -8,6 l 0,5.5 m 11,0 l 0,-5'
  4968. },
  4969. 'TASK_TYPE_USER_2': {
  4970. d: 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' +
  4971. '-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005 '
  4972. },
  4973. 'TASK_TYPE_USER_3': {
  4974. d: 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' +
  4975. '4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' +
  4976. '-4.20799998,3.36699999 -4.20699998,4.34799999 z'
  4977. },
  4978. 'TASK_TYPE_MANUAL': {
  4979. d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' +
  4980. '-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' +
  4981. '0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' +
  4982. '-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' +
  4983. '0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' +
  4984. '-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' +
  4985. '2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' +
  4986. '-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' +
  4987. '-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' +
  4988. '-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' +
  4989. '0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' +
  4990. '-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z'
  4991. },
  4992. 'TASK_TYPE_INSTANTIATING_SEND': {
  4993. d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6'
  4994. },
  4995. 'TASK_TYPE_SERVICE': {
  4996. d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' +
  4997. '0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' +
  4998. '-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' +
  4999. 'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' +
  5000. '-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' +
  5001. '-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' +
  5002. 'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' +
  5003. '-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' +
  5004. 'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' +
  5005. 'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' +
  5006. '0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' +
  5007. 'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' +
  5008. 'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
  5009. '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
  5010. '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
  5011. },
  5012. 'TASK_TYPE_SERVICE_FILL': {
  5013. d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' +
  5014. '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' +
  5015. '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z'
  5016. },
  5017. 'TASK_TYPE_BUSINESS_RULE_HEADER': {
  5018. d: 'm {mx},{my} 0,4 20,0 0,-4 z'
  5019. },
  5020. 'TASK_TYPE_BUSINESS_RULE_MAIN': {
  5021. d: 'm {mx},{my} 0,12 20,0 0,-12 z' +
  5022. 'm 0,8 l 20,0 ' +
  5023. 'm -13,-4 l 0,8'
  5024. },
  5025. 'MESSAGE_FLOW_MARKER': {
  5026. d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6'
  5027. }
  5028. };
  5029. /**
  5030. * Return raw path for the given ID.
  5031. *
  5032. * @param {string} pathId
  5033. *
  5034. * @return {string} raw path
  5035. */
  5036. this.getRawPath = function getRawPath(pathId) {
  5037. return this.pathMap[pathId].d;
  5038. };
  5039. /**
  5040. * Scales the path to the given height and width.
  5041. * <h1>Use case</h1>
  5042. * <p>Use case is to scale the content of elements (event, gateways) based
  5043. * on the element bounding box's size.
  5044. * </p>
  5045. * <h1>Why not transform</h1>
  5046. * <p>Scaling a path with transform() will also scale the stroke and IE does not support
  5047. * the option 'non-scaling-stroke' to prevent this.
  5048. * Also there are use cases where only some parts of a path should be
  5049. * scaled.</p>
  5050. *
  5051. * @param {string} pathId The ID of the path.
  5052. * @param {Object} param <p>
  5053. * Example param object scales the path to 60% size of the container (data.width, data.height).
  5054. * <pre>
  5055. * {
  5056. * xScaleFactor: 0.6,
  5057. * yScaleFactor:0.6,
  5058. * containerWidth: data.width,
  5059. * containerHeight: data.height,
  5060. * position: {
  5061. * mx: 0.46,
  5062. * my: 0.2,
  5063. * }
  5064. * }
  5065. * </pre>
  5066. * <ul>
  5067. * <li>targetpathwidth = xScaleFactor * containerWidth</li>
  5068. * <li>targetpathheight = yScaleFactor * containerHeight</li>
  5069. * <li>Position is used to set the starting coordinate of the path. M is computed:
  5070. * <ul>
  5071. * <li>position.x * containerWidth</li>
  5072. * <li>position.y * containerHeight</li>
  5073. * </ul>
  5074. * Center of the container <pre> position: {
  5075. * mx: 0.5,
  5076. * my: 0.5,
  5077. * }</pre>
  5078. * Upper left corner of the container
  5079. * <pre> position: {
  5080. * mx: 0.0,
  5081. * my: 0.0,
  5082. * }</pre>
  5083. * </li>
  5084. * </ul>
  5085. * </p>
  5086. *
  5087. * @return {string} scaled path
  5088. */
  5089. this.getScaledPath = function getScaledPath(pathId, param) {
  5090. var rawPath = this.pathMap[pathId];
  5091. // positioning
  5092. // compute the start point of the path
  5093. var mx, my;
  5094. if (param.abspos) {
  5095. mx = param.abspos.x;
  5096. my = param.abspos.y;
  5097. } else {
  5098. mx = param.containerWidth * param.position.mx;
  5099. my = param.containerHeight * param.position.my;
  5100. }
  5101. var coordinates = {}; // map for the scaled coordinates
  5102. if (param.position) {
  5103. // path
  5104. var heightRatio = (param.containerHeight / rawPath.height) * param.yScaleFactor;
  5105. var widthRatio = (param.containerWidth / rawPath.width) * param.xScaleFactor;
  5106. // Apply height ratio
  5107. for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) {
  5108. coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio;
  5109. }
  5110. // Apply width ratio
  5111. for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) {
  5112. coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio;
  5113. }
  5114. }
  5115. // Apply value to raw path
  5116. var path = format(
  5117. rawPath.d, {
  5118. mx: mx,
  5119. my: my,
  5120. e: coordinates
  5121. }
  5122. );
  5123. return path;
  5124. };
  5125. }
  5126. // helpers //////////////////////
  5127. // copied and adjusted from https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js
  5128. var tokenRegex = /\{([^{}]+)\}/g,
  5129. objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g; // matches .xxxxx or ["xxxxx"] to run over object properties
  5130. function replacer(all, key, obj) {
  5131. var res = obj;
  5132. key.replace(objNotationRegex, function(all, name, quote, quotedName, isFunc) {
  5133. name = name || quotedName;
  5134. if (res) {
  5135. if (name in res) {
  5136. res = res[name];
  5137. }
  5138. typeof res == 'function' && isFunc && (res = res());
  5139. }
  5140. });
  5141. res = (res == null || res == obj ? all : res) + '';
  5142. return res;
  5143. }
  5144. function format(str, obj) {
  5145. return String(str).replace(tokenRegex, function(all, key) {
  5146. return replacer(all, key, obj);
  5147. });
  5148. }
  5149. var DrawModule$1 = {
  5150. __init__: [ 'bpmnRenderer' ],
  5151. bpmnRenderer: [ 'type', BpmnRenderer ],
  5152. textRenderer: [ 'type', TextRenderer ],
  5153. pathMap: [ 'type', PathMap ]
  5154. };
  5155. /**
  5156. * @typedef { {
  5157. * [key: string]: string;
  5158. * } } TranslateReplacements
  5159. */
  5160. /**
  5161. * A simple translation stub to be used for multi-language support
  5162. * in diagrams. Can be easily replaced with a more sophisticated
  5163. * solution.
  5164. *
  5165. * @example
  5166. *
  5167. * ```javascript
  5168. * // use it inside any diagram component by injecting `translate`.
  5169. *
  5170. * function MyService(translate) {
  5171. * alert(translate('HELLO {you}', { you: 'You!' }));
  5172. * }
  5173. * ```
  5174. *
  5175. * @param {string} template to interpolate
  5176. * @param {TranslateReplacements} [replacements] a map with substitutes
  5177. *
  5178. * @return {string} the translated string
  5179. */
  5180. function translate(template, replacements) {
  5181. replacements = replacements || {};
  5182. return template.replace(/{([^}]+)}/g, function(_, key) {
  5183. return replacements[key] || '{' + key + '}';
  5184. });
  5185. }
  5186. /**
  5187. * @type { import('didi').ModuleDeclaration }
  5188. */
  5189. var TranslateModule = {
  5190. translate: [ 'value', translate ]
  5191. };
  5192. /**
  5193. * @param {Point} point
  5194. *
  5195. * @returns {Point}
  5196. */
  5197. function roundPoint(point) {
  5198. return {
  5199. x: Math.round(point.x),
  5200. y: Math.round(point.y)
  5201. };
  5202. }
  5203. /**
  5204. * Convert the given bounds to a { top, left, bottom, right } descriptor.
  5205. *
  5206. * @param {Point|Rect} bounds
  5207. *
  5208. * @return {RectTRBL}
  5209. */
  5210. function asTRBL(bounds) {
  5211. return {
  5212. top: bounds.y,
  5213. right: bounds.x + (bounds.width || 0),
  5214. bottom: bounds.y + (bounds.height || 0),
  5215. left: bounds.x
  5216. };
  5217. }
  5218. /**
  5219. * Convert a { top, left, bottom, right } to an objects bounds.
  5220. *
  5221. * @param {RectTRBL} trbl
  5222. *
  5223. * @return {Rect}
  5224. */
  5225. function asBounds(trbl) {
  5226. return {
  5227. x: trbl.left,
  5228. y: trbl.top,
  5229. width: trbl.right - trbl.left,
  5230. height: trbl.bottom - trbl.top
  5231. };
  5232. }
  5233. /**
  5234. * Get the mid of the given bounds or point.
  5235. *
  5236. * @param {Point|Rect} bounds
  5237. *
  5238. * @return {Point}
  5239. */
  5240. function getBoundsMid(bounds) {
  5241. return roundPoint({
  5242. x: bounds.x + (bounds.width || 0) / 2,
  5243. y: bounds.y + (bounds.height || 0) / 2
  5244. });
  5245. }
  5246. /**
  5247. * Get the mid of the given Connection.
  5248. *
  5249. * @param {Connection} connection
  5250. *
  5251. * @return {Point}
  5252. */
  5253. function getConnectionMid(connection) {
  5254. var waypoints = connection.waypoints;
  5255. // calculate total length and length of each segment
  5256. var parts = waypoints.reduce(function(parts, point, index) {
  5257. var lastPoint = waypoints[index - 1];
  5258. if (lastPoint) {
  5259. var lastPart = parts[parts.length - 1];
  5260. var startLength = lastPart && lastPart.endLength || 0;
  5261. var length = distance(lastPoint, point);
  5262. parts.push({
  5263. start: lastPoint,
  5264. end: point,
  5265. startLength: startLength,
  5266. endLength: startLength + length,
  5267. length: length
  5268. });
  5269. }
  5270. return parts;
  5271. }, []);
  5272. var totalLength = parts.reduce(function(length, part) {
  5273. return length + part.length;
  5274. }, 0);
  5275. // find which segement contains middle point
  5276. var midLength = totalLength / 2;
  5277. var i = 0;
  5278. var midSegment = parts[i];
  5279. while (midSegment.endLength < midLength) {
  5280. midSegment = parts[++i];
  5281. }
  5282. // calculate relative position on mid segment
  5283. var segmentProgress = (midLength - midSegment.startLength) / midSegment.length;
  5284. var midPoint = {
  5285. x: midSegment.start.x + (midSegment.end.x - midSegment.start.x) * segmentProgress,
  5286. y: midSegment.start.y + (midSegment.end.y - midSegment.start.y) * segmentProgress
  5287. };
  5288. return midPoint;
  5289. }
  5290. /**
  5291. * Get the mid of the given Element.
  5292. *
  5293. * @param {Element} element
  5294. *
  5295. * @return {Point}
  5296. */
  5297. function getMid(element) {
  5298. if (isConnection(element)) {
  5299. return getConnectionMid(element);
  5300. }
  5301. return getBoundsMid(element);
  5302. }
  5303. // helpers //////////////////////
  5304. function distance(a, b) {
  5305. return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
  5306. }
  5307. function elementToString(e) {
  5308. if (!e) {
  5309. return '<null>';
  5310. }
  5311. return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />';
  5312. }
  5313. /**
  5314. * @typedef {import('diagram-js/lib/core/Canvas').default} Canvas
  5315. * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
  5316. * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
  5317. * @typedef {import('diagram-js/lib/i18n/translate/translate').default} Translate
  5318. *
  5319. * @typedef {import('../features/modeling/ElementFactory').default} ElementFactory
  5320. * @typedef {import('../draw/TextRenderer').default} TextRenderer
  5321. *
  5322. * @typedef {import('../model/Types').Element} Element
  5323. * @typedef {import('../model/Types').Label} Label
  5324. * @typedef {import('../model/Types').Shape} Shape
  5325. * @typedef {import('../model/Types').Connection} Connection
  5326. * @typedef {import('../model/Types').Root} Root
  5327. * @typedef {import('../model/Types').ModdleElement} ModdleElement
  5328. */
  5329. /**
  5330. * @param {ModdleElement} semantic
  5331. * @param {ModdleElement} di
  5332. * @param {Object} [attrs=null]
  5333. *
  5334. * @return {Object}
  5335. */
  5336. function elementData(semantic, di, attrs) {
  5337. return assign$1({
  5338. id: semantic.id,
  5339. type: semantic.$type,
  5340. businessObject: semantic,
  5341. di: di
  5342. }, attrs);
  5343. }
  5344. function getWaypoints(di, source, target) {
  5345. var waypoints = di.waypoint;
  5346. if (!waypoints || waypoints.length < 2) {
  5347. return [ getMid(source), getMid(target) ];
  5348. }
  5349. return waypoints.map(function(p) {
  5350. return { x: p.x, y: p.y };
  5351. });
  5352. }
  5353. function notYetDrawn(translate, semantic, refSemantic, property) {
  5354. return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', {
  5355. element: elementToString(refSemantic),
  5356. referenced: elementToString(semantic),
  5357. property: property
  5358. }));
  5359. }
  5360. /**
  5361. * An importer that adds bpmn elements to the canvas
  5362. *
  5363. * @param {EventBus} eventBus
  5364. * @param {Canvas} canvas
  5365. * @param {ElementFactory} elementFactory
  5366. * @param {ElementRegistry} elementRegistry
  5367. * @param {Function} translate
  5368. * @param {TextRenderer} textRenderer
  5369. */
  5370. function BpmnImporter(
  5371. eventBus, canvas, elementFactory,
  5372. elementRegistry, translate, textRenderer) {
  5373. this._eventBus = eventBus;
  5374. this._canvas = canvas;
  5375. this._elementFactory = elementFactory;
  5376. this._elementRegistry = elementRegistry;
  5377. this._translate = translate;
  5378. this._textRenderer = textRenderer;
  5379. }
  5380. BpmnImporter.$inject = [
  5381. 'eventBus',
  5382. 'canvas',
  5383. 'elementFactory',
  5384. 'elementRegistry',
  5385. 'translate',
  5386. 'textRenderer'
  5387. ];
  5388. /**
  5389. * Add a BPMN element (semantic) to the canvas making it a child of the
  5390. * given parent.
  5391. *
  5392. * @param {ModdleElement} semantic
  5393. * @param {ModdleElement} di
  5394. * @param {Shape} parentElement
  5395. *
  5396. * @return {Shape | Root | Connection}
  5397. */
  5398. BpmnImporter.prototype.add = function(semantic, di, parentElement) {
  5399. var element,
  5400. translate = this._translate,
  5401. hidden;
  5402. var parentIndex;
  5403. // ROOT ELEMENT
  5404. // handle the special case that we deal with a
  5405. // invisible root element (process, subprocess or collaboration)
  5406. if (is$1(di, 'bpmndi:BPMNPlane')) {
  5407. var attrs = is$1(semantic, 'bpmn:SubProcess')
  5408. ? { id: semantic.id + '_plane' }
  5409. : {};
  5410. // add a virtual element (not being drawn)
  5411. element = this._elementFactory.createRoot(elementData(semantic, di, attrs));
  5412. this._canvas.addRootElement(element);
  5413. }
  5414. // SHAPE
  5415. else if (is$1(di, 'bpmndi:BPMNShape')) {
  5416. var collapsed = !isExpanded(semantic, di),
  5417. isFrame = isFrameElement$1(semantic);
  5418. hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
  5419. var bounds = di.bounds;
  5420. element = this._elementFactory.createShape(elementData(semantic, di, {
  5421. collapsed: collapsed,
  5422. hidden: hidden,
  5423. x: Math.round(bounds.x),
  5424. y: Math.round(bounds.y),
  5425. width: Math.round(bounds.width),
  5426. height: Math.round(bounds.height),
  5427. isFrame: isFrame
  5428. }));
  5429. if (is$1(semantic, 'bpmn:BoundaryEvent')) {
  5430. this._attachBoundary(semantic, element);
  5431. }
  5432. // insert lanes behind other flow nodes (cf. #727)
  5433. if (is$1(semantic, 'bpmn:Lane')) {
  5434. parentIndex = 0;
  5435. }
  5436. if (is$1(semantic, 'bpmn:DataStoreReference')) {
  5437. // check whether data store is inside our outside of its semantic parent
  5438. if (!isPointInsideBBox(parentElement, getMid(bounds))) {
  5439. parentElement = this._canvas.findRoot(parentElement);
  5440. }
  5441. }
  5442. this._canvas.addShape(element, parentElement, parentIndex);
  5443. }
  5444. // CONNECTION
  5445. else if (is$1(di, 'bpmndi:BPMNEdge')) {
  5446. var source = this._getSource(semantic),
  5447. target = this._getTarget(semantic);
  5448. hidden = parentElement && (parentElement.hidden || parentElement.collapsed);
  5449. element = this._elementFactory.createConnection(elementData(semantic, di, {
  5450. hidden: hidden,
  5451. source: source,
  5452. target: target,
  5453. waypoints: getWaypoints(di, source, target)
  5454. }));
  5455. if (is$1(semantic, 'bpmn:DataAssociation')) {
  5456. // render always on top; this ensures DataAssociations
  5457. // are rendered correctly across different "hacks" people
  5458. // love to model such as cross participant / sub process
  5459. // associations
  5460. parentElement = this._canvas.findRoot(parentElement);
  5461. }
  5462. this._canvas.addConnection(element, parentElement, parentIndex);
  5463. } else {
  5464. throw new Error(translate('unknown di {di} for element {semantic}', {
  5465. di: elementToString(di),
  5466. semantic: elementToString(semantic)
  5467. }));
  5468. }
  5469. // (optional) LABEL
  5470. if (isLabelExternal(semantic) && getLabel(element)) {
  5471. this.addLabel(semantic, di, element);
  5472. }
  5473. this._eventBus.fire('bpmnElement.added', { element: element });
  5474. return element;
  5475. };
  5476. /**
  5477. * Attach a boundary element to the given host.
  5478. *
  5479. * @param {ModdleElement} boundarySemantic
  5480. * @param {Shape} boundaryElement
  5481. */
  5482. BpmnImporter.prototype._attachBoundary = function(boundarySemantic, boundaryElement) {
  5483. var translate = this._translate;
  5484. var hostSemantic = boundarySemantic.attachedToRef;
  5485. if (!hostSemantic) {
  5486. throw new Error(translate('missing {semantic}#attachedToRef', {
  5487. semantic: elementToString(boundarySemantic)
  5488. }));
  5489. }
  5490. var host = this._elementRegistry.get(hostSemantic.id),
  5491. attachers = host && host.attachers;
  5492. if (!host) {
  5493. throw notYetDrawn(translate, boundarySemantic, hostSemantic, 'attachedToRef');
  5494. }
  5495. // wire element.host <> host.attachers
  5496. boundaryElement.host = host;
  5497. if (!attachers) {
  5498. host.attachers = attachers = [];
  5499. }
  5500. if (attachers.indexOf(boundaryElement) === -1) {
  5501. attachers.push(boundaryElement);
  5502. }
  5503. };
  5504. /**
  5505. * Add a label to a given element.
  5506. *
  5507. * @param {ModdleElement} semantic
  5508. * @param {ModdleElement} di
  5509. * @param {Element} element
  5510. *
  5511. * @return {Label}
  5512. */
  5513. BpmnImporter.prototype.addLabel = function(semantic, di, element) {
  5514. var bounds,
  5515. text,
  5516. label;
  5517. bounds = getExternalLabelBounds(di, element);
  5518. text = getLabel(element);
  5519. if (text) {
  5520. // get corrected bounds from actual layouted text
  5521. bounds = this._textRenderer.getExternalLabelBounds(bounds, text);
  5522. }
  5523. label = this._elementFactory.createLabel(elementData(semantic, di, {
  5524. id: semantic.id + '_label',
  5525. labelTarget: element,
  5526. type: 'label',
  5527. hidden: element.hidden || !getLabel(element),
  5528. x: Math.round(bounds.x),
  5529. y: Math.round(bounds.y),
  5530. width: Math.round(bounds.width),
  5531. height: Math.round(bounds.height)
  5532. }));
  5533. return this._canvas.addShape(label, element.parent);
  5534. };
  5535. /**
  5536. * Get the source or target of the given connection.
  5537. *
  5538. * @param {ModdleElement} semantic
  5539. * @param {'source' | 'target'} side
  5540. *
  5541. * @return {Element}
  5542. */
  5543. BpmnImporter.prototype._getConnectedElement = function(semantic, side) {
  5544. var element,
  5545. refSemantic,
  5546. type = semantic.$type,
  5547. translate = this._translate;
  5548. refSemantic = semantic[side + 'Ref'];
  5549. // handle mysterious isMany DataAssociation#sourceRef
  5550. if (side === 'source' && type === 'bpmn:DataInputAssociation') {
  5551. refSemantic = refSemantic && refSemantic[0];
  5552. }
  5553. // fix source / target for DataInputAssociation / DataOutputAssociation
  5554. if (side === 'source' && type === 'bpmn:DataOutputAssociation' ||
  5555. side === 'target' && type === 'bpmn:DataInputAssociation') {
  5556. refSemantic = semantic.$parent;
  5557. }
  5558. element = refSemantic && this._getElement(refSemantic);
  5559. if (element) {
  5560. return element;
  5561. }
  5562. if (refSemantic) {
  5563. throw notYetDrawn(translate, semantic, refSemantic, side + 'Ref');
  5564. } else {
  5565. throw new Error(translate('{semantic}#{side} Ref not specified', {
  5566. semantic: elementToString(semantic),
  5567. side: side
  5568. }));
  5569. }
  5570. };
  5571. BpmnImporter.prototype._getSource = function(semantic) {
  5572. return this._getConnectedElement(semantic, 'source');
  5573. };
  5574. BpmnImporter.prototype._getTarget = function(semantic) {
  5575. return this._getConnectedElement(semantic, 'target');
  5576. };
  5577. BpmnImporter.prototype._getElement = function(semantic) {
  5578. return this._elementRegistry.get(semantic.id);
  5579. };
  5580. // helpers ////////////////////
  5581. function isPointInsideBBox(bbox, point) {
  5582. var x = point.x,
  5583. y = point.y;
  5584. return x >= bbox.x &&
  5585. x <= bbox.x + bbox.width &&
  5586. y >= bbox.y &&
  5587. y <= bbox.y + bbox.height;
  5588. }
  5589. function isFrameElement$1(semantic) {
  5590. return is$1(semantic, 'bpmn:Group');
  5591. }
  5592. var ImportModule = {
  5593. __depends__: [
  5594. TranslateModule
  5595. ],
  5596. bpmnImporter: [ 'type', BpmnImporter ]
  5597. };
  5598. var CoreModule$1 = {
  5599. __depends__: [
  5600. DrawModule$1,
  5601. ImportModule
  5602. ]
  5603. };
  5604. /**
  5605. * @typedef {import('../util/Types').Point} Point
  5606. */
  5607. /**
  5608. * @param {import('../core/EventBus').Event} event
  5609. *
  5610. * @return {Event}
  5611. */
  5612. function getOriginal(event) {
  5613. return event.originalEvent || event.srcEvent;
  5614. }
  5615. function isMac() {
  5616. return (/mac/i).test(navigator.platform);
  5617. }
  5618. /**
  5619. * @param {MouseEvent} event
  5620. * @param {string} button
  5621. *
  5622. * @return {boolean}
  5623. */
  5624. function isButton(event, button) {
  5625. return (getOriginal(event) || event).button === button;
  5626. }
  5627. /**
  5628. * @param {MouseEvent} event
  5629. *
  5630. * @return {boolean}
  5631. */
  5632. function isPrimaryButton(event) {
  5633. // button === 0 -> left áka primary mouse button
  5634. return isButton(event, 0);
  5635. }
  5636. /**
  5637. * @param {MouseEvent} event
  5638. *
  5639. * @return {boolean}
  5640. */
  5641. function isAuxiliaryButton(event) {
  5642. // button === 1 -> auxiliary áka wheel button
  5643. return isButton(event, 1);
  5644. }
  5645. /**
  5646. * @param {MouseEvent} event
  5647. *
  5648. * @return {boolean}
  5649. */
  5650. function hasPrimaryModifier(event) {
  5651. var originalEvent = getOriginal(event) || event;
  5652. if (!isPrimaryButton(event)) {
  5653. return false;
  5654. }
  5655. // Use cmd as primary modifier key for mac OS
  5656. if (isMac()) {
  5657. return originalEvent.metaKey;
  5658. } else {
  5659. return originalEvent.ctrlKey;
  5660. }
  5661. }
  5662. /**
  5663. * @param {MouseEvent} event
  5664. *
  5665. * @return {boolean}
  5666. */
  5667. function hasSecondaryModifier(event) {
  5668. var originalEvent = getOriginal(event) || event;
  5669. return isPrimaryButton(event) && originalEvent.shiftKey;
  5670. }
  5671. /**
  5672. * @typedef {import('../../model/Types').Element} Element
  5673. *
  5674. * @typedef {import('../../core/ElementRegistry').default} ElementRegistry
  5675. * @typedef {import('../../core/EventBus').default} EventBus
  5676. * @typedef {import('../../draw/Styles').default} Styles
  5677. *
  5678. * @typedef {import('../../util/Types').Point} Point
  5679. */
  5680. function allowAll(event) { return true; }
  5681. function allowPrimaryAndAuxiliary(event) {
  5682. return isPrimaryButton(event) || isAuxiliaryButton(event);
  5683. }
  5684. var LOW_PRIORITY$3 = 500;
  5685. /**
  5686. * A plugin that provides interaction events for diagram elements.
  5687. *
  5688. * It emits the following events:
  5689. *
  5690. * * element.click
  5691. * * element.contextmenu
  5692. * * element.dblclick
  5693. * * element.hover
  5694. * * element.mousedown
  5695. * * element.mousemove
  5696. * * element.mouseup
  5697. * * element.out
  5698. *
  5699. * Each event is a tuple { element, gfx, originalEvent }.
  5700. *
  5701. * Canceling the event via Event#preventDefault()
  5702. * prevents the original DOM operation.
  5703. *
  5704. * @param {EventBus} eventBus
  5705. * @param {ElementRegistry} elementRegistry
  5706. * @param {Styles} styles
  5707. */
  5708. function InteractionEvents(eventBus, elementRegistry, styles) {
  5709. var self = this;
  5710. /**
  5711. * Fire an interaction event.
  5712. *
  5713. * @param {string} type local event name, e.g. element.click.
  5714. * @param {MouseEvent|TouchEvent} event native event
  5715. * @param {Element} [element] the diagram element to emit the event on;
  5716. * defaults to the event target
  5717. */
  5718. function fire(type, event, element) {
  5719. if (isIgnored(type, event)) {
  5720. return;
  5721. }
  5722. var target, gfx, returnValue;
  5723. if (!element) {
  5724. target = event.delegateTarget || event.target;
  5725. if (target) {
  5726. gfx = target;
  5727. element = elementRegistry.get(gfx);
  5728. }
  5729. } else {
  5730. gfx = elementRegistry.getGraphics(element);
  5731. }
  5732. if (!gfx || !element) {
  5733. return;
  5734. }
  5735. returnValue = eventBus.fire(type, {
  5736. element: element,
  5737. gfx: gfx,
  5738. originalEvent: event
  5739. });
  5740. if (returnValue === false) {
  5741. event.stopPropagation();
  5742. event.preventDefault();
  5743. }
  5744. }
  5745. // TODO(nikku): document this
  5746. var handlers = {};
  5747. function mouseHandler(localEventName) {
  5748. return handlers[localEventName];
  5749. }
  5750. function isIgnored(localEventName, event) {
  5751. var filter = ignoredFilters[localEventName] || isPrimaryButton;
  5752. // only react on left mouse button interactions
  5753. // except for interaction events that are enabled
  5754. // for secundary mouse button
  5755. return !filter(event);
  5756. }
  5757. var bindings = {
  5758. click: 'element.click',
  5759. contextmenu: 'element.contextmenu',
  5760. dblclick: 'element.dblclick',
  5761. mousedown: 'element.mousedown',
  5762. mousemove: 'element.mousemove',
  5763. mouseover: 'element.hover',
  5764. mouseout: 'element.out',
  5765. mouseup: 'element.mouseup',
  5766. };
  5767. var ignoredFilters = {
  5768. 'element.contextmenu': allowAll,
  5769. 'element.mousedown': allowPrimaryAndAuxiliary,
  5770. 'element.mouseup': allowPrimaryAndAuxiliary,
  5771. 'element.click': allowPrimaryAndAuxiliary,
  5772. 'element.dblclick': allowPrimaryAndAuxiliary
  5773. };
  5774. // manual event trigger //////////
  5775. /**
  5776. * Trigger an interaction event (based on a native dom event)
  5777. * on the target shape or connection.
  5778. *
  5779. * @param {string} eventName the name of the triggered DOM event
  5780. * @param {MouseEvent|TouchEvent} event
  5781. * @param {Element} targetElement
  5782. */
  5783. function triggerMouseEvent(eventName, event, targetElement) {
  5784. // i.e. element.mousedown...
  5785. var localEventName = bindings[eventName];
  5786. if (!localEventName) {
  5787. throw new Error('unmapped DOM event name <' + eventName + '>');
  5788. }
  5789. return fire(localEventName, event, targetElement);
  5790. }
  5791. var ELEMENT_SELECTOR = 'svg, .djs-element';
  5792. // event handling ///////
  5793. function registerEvent(node, event, localEvent, ignoredFilter) {
  5794. var handler = handlers[localEvent] = function(event) {
  5795. fire(localEvent, event);
  5796. };
  5797. if (ignoredFilter) {
  5798. ignoredFilters[localEvent] = ignoredFilter;
  5799. }
  5800. handler.$delegate = delegate.bind(node, ELEMENT_SELECTOR, event, handler);
  5801. }
  5802. function unregisterEvent(node, event, localEvent) {
  5803. var handler = mouseHandler(localEvent);
  5804. if (!handler) {
  5805. return;
  5806. }
  5807. delegate.unbind(node, event, handler.$delegate);
  5808. }
  5809. function registerEvents(svg) {
  5810. forEach$1(bindings, function(val, key) {
  5811. registerEvent(svg, key, val);
  5812. });
  5813. }
  5814. function unregisterEvents(svg) {
  5815. forEach$1(bindings, function(val, key) {
  5816. unregisterEvent(svg, key, val);
  5817. });
  5818. }
  5819. eventBus.on('canvas.destroy', function(event) {
  5820. unregisterEvents(event.svg);
  5821. });
  5822. eventBus.on('canvas.init', function(event) {
  5823. registerEvents(event.svg);
  5824. });
  5825. // hit box updating ////////////////
  5826. eventBus.on([ 'shape.added', 'connection.added' ], function(event) {
  5827. var element = event.element,
  5828. gfx = event.gfx;
  5829. eventBus.fire('interactionEvents.createHit', { element: element, gfx: gfx });
  5830. });
  5831. // Update djs-hit on change.
  5832. // A low priortity is necessary, because djs-hit of labels has to be updated
  5833. // after the label bounds have been updated in the renderer.
  5834. eventBus.on([
  5835. 'shape.changed',
  5836. 'connection.changed'
  5837. ], LOW_PRIORITY$3, function(event) {
  5838. var element = event.element,
  5839. gfx = event.gfx;
  5840. eventBus.fire('interactionEvents.updateHit', { element: element, gfx: gfx });
  5841. });
  5842. eventBus.on('interactionEvents.createHit', LOW_PRIORITY$3, function(event) {
  5843. var element = event.element,
  5844. gfx = event.gfx;
  5845. self.createDefaultHit(element, gfx);
  5846. });
  5847. eventBus.on('interactionEvents.updateHit', function(event) {
  5848. var element = event.element,
  5849. gfx = event.gfx;
  5850. self.updateDefaultHit(element, gfx);
  5851. });
  5852. // hit styles ////////////
  5853. var STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-stroke');
  5854. var CLICK_STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-click-stroke');
  5855. var ALL_HIT_STYLE = createHitStyle('djs-hit djs-hit-all');
  5856. var NO_MOVE_HIT_STYLE = createHitStyle('djs-hit djs-hit-no-move');
  5857. var HIT_TYPES = {
  5858. 'all': ALL_HIT_STYLE,
  5859. 'click-stroke': CLICK_STROKE_HIT_STYLE,
  5860. 'stroke': STROKE_HIT_STYLE,
  5861. 'no-move': NO_MOVE_HIT_STYLE
  5862. };
  5863. function createHitStyle(classNames, attrs) {
  5864. attrs = assign$1({
  5865. stroke: 'white',
  5866. strokeWidth: 15
  5867. }, attrs || {});
  5868. return styles.cls(classNames, [ 'no-fill', 'no-border' ], attrs);
  5869. }
  5870. // style helpers ///////////////
  5871. function applyStyle(hit, type) {
  5872. var attrs = HIT_TYPES[type];
  5873. if (!attrs) {
  5874. throw new Error('invalid hit type <' + type + '>');
  5875. }
  5876. attr$1(hit, attrs);
  5877. return hit;
  5878. }
  5879. function appendHit(gfx, hit) {
  5880. append(gfx, hit);
  5881. }
  5882. // API
  5883. /**
  5884. * Remove hints on the given graphics.
  5885. *
  5886. * @param {SVGElement} gfx
  5887. */
  5888. this.removeHits = function(gfx) {
  5889. var hits = all('.djs-hit', gfx);
  5890. forEach$1(hits, remove$2);
  5891. };
  5892. /**
  5893. * Create default hit for the given element.
  5894. *
  5895. * @param {Element} element
  5896. * @param {SVGElement} gfx
  5897. *
  5898. * @return {SVGElement} created hit
  5899. */
  5900. this.createDefaultHit = function(element, gfx) {
  5901. var waypoints = element.waypoints,
  5902. isFrame = element.isFrame,
  5903. boxType;
  5904. if (waypoints) {
  5905. return this.createWaypointsHit(gfx, waypoints);
  5906. } else {
  5907. boxType = isFrame ? 'stroke' : 'all';
  5908. return this.createBoxHit(gfx, boxType, {
  5909. width: element.width,
  5910. height: element.height
  5911. });
  5912. }
  5913. };
  5914. /**
  5915. * Create hits for the given waypoints.
  5916. *
  5917. * @param {SVGElement} gfx
  5918. * @param {Point[]} waypoints
  5919. *
  5920. * @return {SVGElement}
  5921. */
  5922. this.createWaypointsHit = function(gfx, waypoints) {
  5923. var hit = createLine(waypoints);
  5924. applyStyle(hit, 'stroke');
  5925. appendHit(gfx, hit);
  5926. return hit;
  5927. };
  5928. /**
  5929. * Create hits for a box.
  5930. *
  5931. * @param {SVGElement} gfx
  5932. * @param {string} type
  5933. * @param {Object} attrs
  5934. *
  5935. * @return {SVGElement}
  5936. */
  5937. this.createBoxHit = function(gfx, type, attrs) {
  5938. attrs = assign$1({
  5939. x: 0,
  5940. y: 0
  5941. }, attrs);
  5942. var hit = create$1('rect');
  5943. applyStyle(hit, type);
  5944. attr$1(hit, attrs);
  5945. appendHit(gfx, hit);
  5946. return hit;
  5947. };
  5948. /**
  5949. * Update default hit of the element.
  5950. *
  5951. * @param {Element} element
  5952. * @param {SVGElement} gfx
  5953. *
  5954. * @return {SVGElement} updated hit
  5955. */
  5956. this.updateDefaultHit = function(element, gfx) {
  5957. var hit = query('.djs-hit', gfx);
  5958. if (!hit) {
  5959. return;
  5960. }
  5961. if (element.waypoints) {
  5962. updateLine(hit, element.waypoints);
  5963. } else {
  5964. attr$1(hit, {
  5965. width: element.width,
  5966. height: element.height
  5967. });
  5968. }
  5969. return hit;
  5970. };
  5971. this.fire = fire;
  5972. this.triggerMouseEvent = triggerMouseEvent;
  5973. this.mouseHandler = mouseHandler;
  5974. this.registerEvent = registerEvent;
  5975. this.unregisterEvent = unregisterEvent;
  5976. }
  5977. InteractionEvents.$inject = [
  5978. 'eventBus',
  5979. 'elementRegistry',
  5980. 'styles'
  5981. ];
  5982. /**
  5983. * An event indicating that the mouse hovered over an element
  5984. *
  5985. * @event element.hover
  5986. *
  5987. * @type {Object}
  5988. * @property {Element} element
  5989. * @property {SVGElement} gfx
  5990. * @property {Event} originalEvent
  5991. */
  5992. /**
  5993. * An event indicating that the mouse has left an element
  5994. *
  5995. * @event element.out
  5996. *
  5997. * @type {Object}
  5998. * @property {Element} element
  5999. * @property {SVGElement} gfx
  6000. * @property {Event} originalEvent
  6001. */
  6002. /**
  6003. * An event indicating that the mouse has clicked an element
  6004. *
  6005. * @event element.click
  6006. *
  6007. * @type {Object}
  6008. * @property {Element} element
  6009. * @property {SVGElement} gfx
  6010. * @property {Event} originalEvent
  6011. */
  6012. /**
  6013. * An event indicating that the mouse has double clicked an element
  6014. *
  6015. * @event element.dblclick
  6016. *
  6017. * @type {Object}
  6018. * @property {Element} element
  6019. * @property {SVGElement} gfx
  6020. * @property {Event} originalEvent
  6021. */
  6022. /**
  6023. * An event indicating that the mouse has gone down on an element.
  6024. *
  6025. * @event element.mousedown
  6026. *
  6027. * @type {Object}
  6028. * @property {Element} element
  6029. * @property {SVGElement} gfx
  6030. * @property {Event} originalEvent
  6031. */
  6032. /**
  6033. * An event indicating that the mouse has gone up on an element.
  6034. *
  6035. * @event element.mouseup
  6036. *
  6037. * @type {Object}
  6038. * @property {Element} element
  6039. * @property {SVGElement} gfx
  6040. * @property {Event} originalEvent
  6041. */
  6042. /**
  6043. * An event indicating that the context menu action is triggered
  6044. * via mouse or touch controls.
  6045. *
  6046. * @event element.contextmenu
  6047. *
  6048. * @type {Object}
  6049. * @property {Element} element
  6050. * @property {SVGElement} gfx
  6051. * @property {Event} originalEvent
  6052. */
  6053. /**
  6054. * @type { import('didi').ModuleDeclaration }
  6055. */
  6056. var InteractionEventsModule = {
  6057. __init__: [ 'interactionEvents' ],
  6058. interactionEvents: [ 'type', InteractionEvents ]
  6059. };
  6060. /**
  6061. * Returns the surrounding bbox for all elements in
  6062. * the array or the element primitive.
  6063. *
  6064. * @param {Element|Element[]} elements
  6065. * @param {boolean} [stopRecursion=false]
  6066. *
  6067. * @return {Rect}
  6068. */
  6069. function getBBox(elements, stopRecursion) {
  6070. stopRecursion = !!stopRecursion;
  6071. if (!isArray$2(elements)) {
  6072. elements = [ elements ];
  6073. }
  6074. var minX,
  6075. minY,
  6076. maxX,
  6077. maxY;
  6078. forEach$1(elements, function(element) {
  6079. // If element is a connection the bbox must be computed first
  6080. var bbox = element;
  6081. if (element.waypoints && !stopRecursion) {
  6082. bbox = getBBox(element.waypoints, true);
  6083. }
  6084. var x = bbox.x,
  6085. y = bbox.y,
  6086. height = bbox.height || 0,
  6087. width = bbox.width || 0;
  6088. if (x < minX || minX === undefined) {
  6089. minX = x;
  6090. }
  6091. if (y < minY || minY === undefined) {
  6092. minY = y;
  6093. }
  6094. if ((x + width) > maxX || maxX === undefined) {
  6095. maxX = x + width;
  6096. }
  6097. if ((y + height) > maxY || maxY === undefined) {
  6098. maxY = y + height;
  6099. }
  6100. });
  6101. return {
  6102. x: minX,
  6103. y: minY,
  6104. height: maxY - minY,
  6105. width: maxX - minX
  6106. };
  6107. }
  6108. /**
  6109. * Get the element's type
  6110. *
  6111. * @param {Element} element
  6112. *
  6113. * @return {'connection' | 'shape' | 'root'}
  6114. */
  6115. function getType(element) {
  6116. if ('waypoints' in element) {
  6117. return 'connection';
  6118. }
  6119. if ('x' in element) {
  6120. return 'shape';
  6121. }
  6122. return 'root';
  6123. }
  6124. /**
  6125. * @param {Element} element
  6126. *
  6127. * @return {boolean}
  6128. */
  6129. function isFrameElement(element) {
  6130. return !!(element && element.isFrame);
  6131. }
  6132. var LOW_PRIORITY$2 = 500;
  6133. var DEFAULT_PRIORITY$2 = 1000;
  6134. /**
  6135. * @typedef {import('../../model/Types').Element} Element
  6136. *
  6137. * @typedef {import('../../core/EventBus').default} EventBus
  6138. * @typedef {import('../../draw/Styles').default} Styles
  6139. */
  6140. /**
  6141. * @class
  6142. *
  6143. * A plugin that adds an outline to shapes and connections that may be activated and styled
  6144. * via CSS classes.
  6145. *
  6146. * @param {EventBus} eventBus
  6147. * @param {Styles} styles
  6148. */
  6149. function Outline(eventBus, styles) {
  6150. this._eventBus = eventBus;
  6151. this.offset = 5;
  6152. var OUTLINE_STYLE = styles.cls('djs-outline', [ 'no-fill' ]);
  6153. var self = this;
  6154. /**
  6155. * @param {SVGElement} gfx
  6156. *
  6157. * @return {SVGElement} outline
  6158. */
  6159. function createOutline(gfx) {
  6160. var outline = create$1('rect');
  6161. attr$1(outline, assign$1({
  6162. x: 0,
  6163. y: 0,
  6164. rx: 4,
  6165. width: 100,
  6166. height: 100
  6167. }, OUTLINE_STYLE));
  6168. return outline;
  6169. }
  6170. // A low priortity is necessary, because outlines of labels have to be updated
  6171. // after the label bounds have been updated in the renderer.
  6172. eventBus.on([ 'shape.added', 'shape.changed' ], LOW_PRIORITY$2, function(event) {
  6173. var element = event.element,
  6174. gfx = event.gfx;
  6175. var outline = query('.djs-outline', gfx);
  6176. if (!outline) {
  6177. outline = self.getOutline(element) || createOutline();
  6178. append(gfx, outline);
  6179. }
  6180. self.updateShapeOutline(outline, element);
  6181. });
  6182. eventBus.on([ 'connection.added', 'connection.changed' ], function(event) {
  6183. var element = event.element,
  6184. gfx = event.gfx;
  6185. var outline = query('.djs-outline', gfx);
  6186. if (!outline) {
  6187. outline = createOutline();
  6188. append(gfx, outline);
  6189. }
  6190. self.updateConnectionOutline(outline, element);
  6191. });
  6192. }
  6193. /**
  6194. * Updates the outline of a shape respecting the dimension of the
  6195. * element and an outline offset.
  6196. *
  6197. * @param {SVGElement} outline
  6198. * @param {Element} element
  6199. */
  6200. Outline.prototype.updateShapeOutline = function(outline, element) {
  6201. var updated = false;
  6202. var providers = this._getProviders();
  6203. if (providers.length) {
  6204. forEach$1(providers, function(provider) {
  6205. updated = updated || provider.updateOutline(element, outline);
  6206. });
  6207. }
  6208. if (!updated) {
  6209. attr$1(outline, {
  6210. x: -this.offset,
  6211. y: -this.offset,
  6212. width: element.width + this.offset * 2,
  6213. height: element.height + this.offset * 2
  6214. });
  6215. }
  6216. };
  6217. /**
  6218. * Updates the outline of a connection respecting the bounding box of
  6219. * the connection and an outline offset.
  6220. * Register an outline provider with the given priority.
  6221. *
  6222. * @param {SVGElement} outline
  6223. * @param {Element} connection
  6224. */
  6225. Outline.prototype.updateConnectionOutline = function(outline, connection) {
  6226. var bbox = getBBox(connection);
  6227. attr$1(outline, {
  6228. x: bbox.x - this.offset,
  6229. y: bbox.y - this.offset,
  6230. width: bbox.width + this.offset * 2,
  6231. height: bbox.height + this.offset * 2
  6232. });
  6233. };
  6234. /**
  6235. * Register an outline provider with the given priority.
  6236. *
  6237. * @param {number} priority
  6238. * @param {OutlineProvider} provider
  6239. */
  6240. Outline.prototype.registerProvider = function(priority, provider) {
  6241. if (!provider) {
  6242. provider = priority;
  6243. priority = DEFAULT_PRIORITY$2;
  6244. }
  6245. this._eventBus.on('outline.getProviders', priority, function(event) {
  6246. event.providers.push(provider);
  6247. });
  6248. };
  6249. /**
  6250. * Returns the registered outline providers.
  6251. *
  6252. * @returns {OutlineProvider[]}
  6253. */
  6254. Outline.prototype._getProviders = function() {
  6255. var event = this._eventBus.createEvent({
  6256. type: 'outline.getProviders',
  6257. providers: []
  6258. });
  6259. this._eventBus.fire(event);
  6260. return event.providers;
  6261. };
  6262. /**
  6263. * Returns the outline for an element.
  6264. *
  6265. * @param {Element} element
  6266. **/
  6267. Outline.prototype.getOutline = function(element) {
  6268. var outline;
  6269. var providers = this._getProviders();
  6270. forEach$1(providers, function(provider) {
  6271. if (!isFunction(provider.getOutline)) {
  6272. return;
  6273. }
  6274. outline = outline || provider.getOutline(element);
  6275. });
  6276. return outline;
  6277. };
  6278. Outline.$inject = [ 'eventBus', 'styles', 'elementRegistry' ];
  6279. /**
  6280. * @type { import('didi').ModuleDeclaration }
  6281. */
  6282. var OutlineModule = {
  6283. __init__: [ 'outline' ],
  6284. outline: [ 'type', Outline ]
  6285. };
  6286. /**
  6287. * @typedef {import('../../core/Canvas').default} Canvas
  6288. * @typedef {import('../../core/EventBus').default} EventBus
  6289. */
  6290. /**
  6291. * A service that offers the current selection in a diagram.
  6292. * Offers the api to control the selection, too.
  6293. *
  6294. * @param {EventBus} eventBus
  6295. * @param {Canvas} canvas
  6296. */
  6297. function Selection(eventBus, canvas) {
  6298. this._eventBus = eventBus;
  6299. this._canvas = canvas;
  6300. /**
  6301. * @type {Object[]}
  6302. */
  6303. this._selectedElements = [];
  6304. var self = this;
  6305. eventBus.on([ 'shape.remove', 'connection.remove' ], function(e) {
  6306. var element = e.element;
  6307. self.deselect(element);
  6308. });
  6309. eventBus.on([ 'diagram.clear', 'root.set' ], function(e) {
  6310. self.select(null);
  6311. });
  6312. }
  6313. Selection.$inject = [ 'eventBus', 'canvas' ];
  6314. /**
  6315. * Deselect an element.
  6316. *
  6317. * @param {Object} element The element to deselect.
  6318. */
  6319. Selection.prototype.deselect = function(element) {
  6320. var selectedElements = this._selectedElements;
  6321. var idx = selectedElements.indexOf(element);
  6322. if (idx !== -1) {
  6323. var oldSelection = selectedElements.slice();
  6324. selectedElements.splice(idx, 1);
  6325. this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements });
  6326. }
  6327. };
  6328. /**
  6329. * Get the selected elements.
  6330. *
  6331. * @return {Object[]} The selected elements.
  6332. */
  6333. Selection.prototype.get = function() {
  6334. return this._selectedElements;
  6335. };
  6336. /**
  6337. * Check whether an element is selected.
  6338. *
  6339. * @param {Object} element The element.
  6340. *
  6341. * @return {boolean} Whether the element is selected.
  6342. */
  6343. Selection.prototype.isSelected = function(element) {
  6344. return this._selectedElements.indexOf(element) !== -1;
  6345. };
  6346. /**
  6347. * Select one or many elements.
  6348. *
  6349. * @param {Object|Object[]} elements The element(s) to select.
  6350. * @param {boolean} [add] Whether to add the element(s) to the selected elements.
  6351. * Defaults to `false`.
  6352. */
  6353. Selection.prototype.select = function(elements, add) {
  6354. var selectedElements = this._selectedElements,
  6355. oldSelection = selectedElements.slice();
  6356. if (!isArray$2(elements)) {
  6357. elements = elements ? [ elements ] : [];
  6358. }
  6359. var canvas = this._canvas;
  6360. var rootElement = canvas.getRootElement();
  6361. elements = elements.filter(function(element) {
  6362. var elementRoot = canvas.findRoot(element);
  6363. return rootElement === elementRoot;
  6364. });
  6365. // selection may be cleared by passing an empty array or null
  6366. // to the method
  6367. if (add) {
  6368. forEach$1(elements, function(element) {
  6369. if (selectedElements.indexOf(element) !== -1) {
  6370. // already selected
  6371. return;
  6372. } else {
  6373. selectedElements.push(element);
  6374. }
  6375. });
  6376. } else {
  6377. this._selectedElements = selectedElements = elements.slice();
  6378. }
  6379. this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements });
  6380. };
  6381. /**
  6382. * @typedef {import('../../core/Canvas').default} Canvas
  6383. * @typedef {import('../../core/EventBus').default} EventBus
  6384. * @typedef {import('./Selection').default} Selection
  6385. */
  6386. var MARKER_HOVER = 'hover',
  6387. MARKER_SELECTED = 'selected';
  6388. var SELECTION_OUTLINE_PADDING = 6;
  6389. /**
  6390. * A plugin that adds a visible selection UI to shapes and connections
  6391. * by appending the <code>hover</code> and <code>selected</code> classes to them.
  6392. *
  6393. * @class
  6394. *
  6395. * Makes elements selectable, too.
  6396. *
  6397. * @param {Canvas} canvas
  6398. * @param {EventBus} eventBus
  6399. * @param {Selection} selection
  6400. */
  6401. function SelectionVisuals(canvas, eventBus, selection) {
  6402. this._canvas = canvas;
  6403. var self = this;
  6404. this._multiSelectionBox = null;
  6405. function addMarker(e, cls) {
  6406. canvas.addMarker(e, cls);
  6407. }
  6408. function removeMarker(e, cls) {
  6409. canvas.removeMarker(e, cls);
  6410. }
  6411. eventBus.on('element.hover', function(event) {
  6412. addMarker(event.element, MARKER_HOVER);
  6413. });
  6414. eventBus.on('element.out', function(event) {
  6415. removeMarker(event.element, MARKER_HOVER);
  6416. });
  6417. eventBus.on('selection.changed', function(event) {
  6418. function deselect(s) {
  6419. removeMarker(s, MARKER_SELECTED);
  6420. }
  6421. function select(s) {
  6422. addMarker(s, MARKER_SELECTED);
  6423. }
  6424. var oldSelection = event.oldSelection,
  6425. newSelection = event.newSelection;
  6426. forEach$1(oldSelection, function(e) {
  6427. if (newSelection.indexOf(e) === -1) {
  6428. deselect(e);
  6429. }
  6430. });
  6431. forEach$1(newSelection, function(e) {
  6432. if (oldSelection.indexOf(e) === -1) {
  6433. select(e);
  6434. }
  6435. });
  6436. self._updateSelectionOutline(newSelection);
  6437. });
  6438. eventBus.on('element.changed', function(event) {
  6439. if (selection.isSelected(event.element)) {
  6440. self._updateSelectionOutline(selection.get());
  6441. }
  6442. });
  6443. }
  6444. SelectionVisuals.$inject = [
  6445. 'canvas',
  6446. 'eventBus',
  6447. 'selection'
  6448. ];
  6449. SelectionVisuals.prototype._updateSelectionOutline = function(selection) {
  6450. var layer = this._canvas.getLayer('selectionOutline');
  6451. clear$1(layer);
  6452. var enabled = selection.length > 1;
  6453. var container = this._canvas.getContainer();
  6454. classes$1(container)[enabled ? 'add' : 'remove']('djs-multi-select');
  6455. if (!enabled) {
  6456. return;
  6457. }
  6458. var bBox = addSelectionOutlinePadding(getBBox(selection));
  6459. var rect = create$1('rect');
  6460. attr$1(rect, assign$1({
  6461. rx: 3
  6462. }, bBox));
  6463. classes$1(rect).add('djs-selection-outline');
  6464. append(layer, rect);
  6465. };
  6466. // helpers //////////
  6467. function addSelectionOutlinePadding(bBox) {
  6468. return {
  6469. x: bBox.x - SELECTION_OUTLINE_PADDING,
  6470. y: bBox.y - SELECTION_OUTLINE_PADDING,
  6471. width: bBox.width + SELECTION_OUTLINE_PADDING * 2,
  6472. height: bBox.height + SELECTION_OUTLINE_PADDING * 2
  6473. };
  6474. }
  6475. /**
  6476. * @typedef {import('../../core/Canvas').default} Canvas
  6477. * @typedef {import('../../core/ElementRegistry').default} ElementRegistry
  6478. * @typedef {import('../../core/EventBus').default} EventBus
  6479. * @typedef {import('./Selection').default} Selection
  6480. */
  6481. /**
  6482. * @param {EventBus} eventBus
  6483. * @param {Selection} selection
  6484. * @param {Canvas} canvas
  6485. * @param {ElementRegistry} elementRegistry
  6486. */
  6487. function SelectionBehavior(eventBus, selection, canvas, elementRegistry) {
  6488. // Select elements on create
  6489. eventBus.on('create.end', 500, function(event) {
  6490. var context = event.context,
  6491. canExecute = context.canExecute,
  6492. elements = context.elements,
  6493. hints = context.hints || {},
  6494. autoSelect = hints.autoSelect;
  6495. if (canExecute) {
  6496. if (autoSelect === false) {
  6497. // Select no elements
  6498. return;
  6499. }
  6500. if (isArray$2(autoSelect)) {
  6501. selection.select(autoSelect);
  6502. } else {
  6503. // Select all elements by default
  6504. selection.select(elements.filter(isShown));
  6505. }
  6506. }
  6507. });
  6508. // Select connection targets on connect
  6509. eventBus.on('connect.end', 500, function(event) {
  6510. var context = event.context,
  6511. connection = context.connection;
  6512. if (connection) {
  6513. selection.select(connection);
  6514. }
  6515. });
  6516. // Select shapes on move
  6517. eventBus.on('shape.move.end', 500, function(event) {
  6518. var previousSelection = event.previousSelection || [];
  6519. var shape = elementRegistry.get(event.context.shape.id);
  6520. // Always select main shape on move
  6521. var isSelected = find(previousSelection, function(selectedShape) {
  6522. return shape.id === selectedShape.id;
  6523. });
  6524. if (!isSelected) {
  6525. selection.select(shape);
  6526. }
  6527. });
  6528. // Select elements on click
  6529. eventBus.on('element.click', function(event) {
  6530. if (!isPrimaryButton(event)) {
  6531. return;
  6532. }
  6533. var element = event.element;
  6534. if (element === canvas.getRootElement()) {
  6535. element = null;
  6536. }
  6537. var isSelected = selection.isSelected(element),
  6538. isMultiSelect = selection.get().length > 1;
  6539. // Add to selection if CTRL or SHIFT pressed
  6540. var add = hasPrimaryModifier(event) || hasSecondaryModifier(event);
  6541. if (isSelected && isMultiSelect) {
  6542. if (add) {
  6543. // Deselect element
  6544. return selection.deselect(element);
  6545. } else {
  6546. // Select element only
  6547. return selection.select(element);
  6548. }
  6549. } else if (!isSelected) {
  6550. // Select element
  6551. selection.select(element, add);
  6552. } else {
  6553. // Deselect element
  6554. selection.deselect(element);
  6555. }
  6556. });
  6557. }
  6558. SelectionBehavior.$inject = [
  6559. 'eventBus',
  6560. 'selection',
  6561. 'canvas',
  6562. 'elementRegistry'
  6563. ];
  6564. function isShown(element) {
  6565. return !element.hidden;
  6566. }
  6567. /**
  6568. * @type { import('didi').ModuleDeclaration }
  6569. */
  6570. var SelectionModule = {
  6571. __init__: [ 'selectionVisuals', 'selectionBehavior' ],
  6572. __depends__: [
  6573. InteractionEventsModule,
  6574. OutlineModule
  6575. ],
  6576. selection: [ 'type', Selection ],
  6577. selectionVisuals: [ 'type', SelectionVisuals ],
  6578. selectionBehavior: [ 'type', SelectionBehavior ]
  6579. };
  6580. /**
  6581. * Util that provides unique IDs.
  6582. *
  6583. * @class
  6584. * @constructor
  6585. *
  6586. * The ids can be customized via a given prefix and contain a random value to avoid collisions.
  6587. *
  6588. * @param {string} [prefix] a prefix to prepend to generated ids (for better readability)
  6589. */
  6590. function IdGenerator(prefix) {
  6591. this._counter = 0;
  6592. this._prefix = (prefix ? prefix + '-' : '') + Math.floor(Math.random() * 1000000000) + '-';
  6593. }
  6594. /**
  6595. * Returns a next unique ID.
  6596. *
  6597. * @return {string} the id
  6598. */
  6599. IdGenerator.prototype.next = function() {
  6600. return this._prefix + (++this._counter);
  6601. };
  6602. // document wide unique overlay ids
  6603. var ids = new IdGenerator('ov');
  6604. var LOW_PRIORITY$1 = 500;
  6605. /**
  6606. * @typedef {import('../../core/Canvas').default} Canvas
  6607. * @typedef {import('../../core/ElementRegistry').default} ElementRegistry
  6608. * @typedef {import('../../core/EventBus').default} EventBus
  6609. *
  6610. * @typedef {import('../../model/Types').Element} Element
  6611. *
  6612. * @typedef { {
  6613. * minZoom?: number,
  6614. * maxZoom?: number
  6615. * } } OverlaysConfigShow
  6616. *
  6617. * @typedef { {
  6618. * min?: number,
  6619. * max?: number
  6620. * } } OverlaysConfigScale
  6621. *
  6622. * @typedef { {
  6623. * id: string,
  6624. * type: string | null,
  6625. * element: Element | string
  6626. * } & OverlayAttrs } Overlay
  6627. *
  6628. * @typedef { {
  6629. * html: HTMLElement | string,
  6630. * position: {
  6631. * top?: number,
  6632. * right?: number,
  6633. * bottom?: number,
  6634. * left?: number
  6635. * }
  6636. * } & OverlaysConfigDefault } OverlayAttrs
  6637. *
  6638. * @typedef { {
  6639. * html: HTMLElement,
  6640. * element: Element,
  6641. * overlays: Overlay[]
  6642. * } } OverlayContainer
  6643. *
  6644. * @typedef {{
  6645. * defaults?: OverlaysConfigDefault
  6646. * }} OverlaysConfig
  6647. *
  6648. * @typedef { {
  6649. * show?: OverlaysConfigShow,
  6650. * scale?: OverlaysConfigScale | boolean
  6651. * } } OverlaysConfigDefault
  6652. *
  6653. * @typedef { {
  6654. * id?: string;
  6655. * element?: Element | string;
  6656. * type?: string;
  6657. * } | string } OverlaysFilter
  6658. */
  6659. /**
  6660. * A service that allows users to attach overlays to diagram elements.
  6661. *
  6662. * The overlay service will take care of overlay positioning during updates.
  6663. *
  6664. * @example
  6665. *
  6666. * ```javascript
  6667. * // add a pink badge on the top left of the shape
  6668. *
  6669. * overlays.add(someShape, {
  6670. * position: {
  6671. * top: -5,
  6672. * left: -5
  6673. * },
  6674. * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
  6675. * });
  6676. *
  6677. * // or add via shape id
  6678. *
  6679. * overlays.add('some-element-id', {
  6680. * position: {
  6681. * top: -5,
  6682. * left: -5
  6683. * }
  6684. * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
  6685. * });
  6686. *
  6687. * // or add with optional type
  6688. *
  6689. * overlays.add(someShape, 'badge', {
  6690. * position: {
  6691. * top: -5,
  6692. * left: -5
  6693. * }
  6694. * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>'
  6695. * });
  6696. * ```
  6697. *
  6698. * ```javascript
  6699. * // remove an overlay
  6700. *
  6701. * var id = overlays.add(...);
  6702. * overlays.remove(id);
  6703. *
  6704. *
  6705. * You may configure overlay defaults during tool by providing a `config` module
  6706. * with `overlays.defaults` as an entry:
  6707. *
  6708. * {
  6709. * overlays: {
  6710. * defaults: {
  6711. * show: {
  6712. * minZoom: 0.7,
  6713. * maxZoom: 5.0
  6714. * },
  6715. * scale: {
  6716. * min: 1
  6717. * }
  6718. * }
  6719. * }
  6720. * ```
  6721. *
  6722. * @param {OverlaysConfig} config
  6723. * @param {EventBus} eventBus
  6724. * @param {Canvas} canvas
  6725. * @param {ElementRegistry} elementRegistry
  6726. */
  6727. function Overlays(config, eventBus, canvas, elementRegistry) {
  6728. this._eventBus = eventBus;
  6729. this._canvas = canvas;
  6730. this._elementRegistry = elementRegistry;
  6731. this._ids = ids;
  6732. /**
  6733. * @type {OverlaysConfigDefault}
  6734. */
  6735. this._overlayDefaults = assign$1({
  6736. // no show constraints
  6737. show: null,
  6738. // always scale
  6739. scale: true
  6740. }, config && config.defaults);
  6741. /**
  6742. * @type {Map<string, Overlay>}
  6743. */
  6744. this._overlays = {};
  6745. /**
  6746. * @type {OverlayContainer[]}
  6747. */
  6748. this._overlayContainers = [];
  6749. /**
  6750. * @type {HTMLElement}
  6751. */
  6752. this._overlayRoot = createRoot(canvas.getContainer());
  6753. this._init();
  6754. }
  6755. Overlays.$inject = [
  6756. 'config.overlays',
  6757. 'eventBus',
  6758. 'canvas',
  6759. 'elementRegistry'
  6760. ];
  6761. /**
  6762. * Returns the overlay with the specified ID or a list of overlays
  6763. * for an element with a given type.
  6764. *
  6765. * @example
  6766. *
  6767. * ```javascript
  6768. * // return the single overlay with the given ID
  6769. * overlays.get('some-id');
  6770. *
  6771. * // return all overlays for the shape
  6772. * overlays.get({ element: someShape });
  6773. *
  6774. * // return all overlays on shape with type 'badge'
  6775. * overlays.get({ element: someShape, type: 'badge' });
  6776. *
  6777. * // shape can also be specified as ID
  6778. * overlays.get({ element: 'element-id', type: 'badge' });
  6779. * ```
  6780. *
  6781. * @param {OverlaysFilter} search The filter to be used to find the overlay(s).
  6782. *
  6783. * @return {Overlay|Overlay[]} The overlay(s).
  6784. */
  6785. Overlays.prototype.get = function(search) {
  6786. if (isString(search)) {
  6787. search = { id: search };
  6788. }
  6789. if (isString(search.element)) {
  6790. search.element = this._elementRegistry.get(search.element);
  6791. }
  6792. if (search.element) {
  6793. var container = this._getOverlayContainer(search.element, true);
  6794. // return a list of overlays when searching by element (+type)
  6795. if (container) {
  6796. return search.type ? filter(container.overlays, matchPattern({ type: search.type })) : container.overlays.slice();
  6797. } else {
  6798. return [];
  6799. }
  6800. } else
  6801. if (search.type) {
  6802. return filter(this._overlays, matchPattern({ type: search.type }));
  6803. } else {
  6804. // return single element when searching by id
  6805. return search.id ? this._overlays[search.id] : null;
  6806. }
  6807. };
  6808. /**
  6809. * Adds an HTML overlay to an element.
  6810. *
  6811. * @param {Element|string} element The element to add the overlay to.
  6812. * @param {string} [type] An optional type that can be used to filter.
  6813. * @param {OverlayAttrs} overlay The overlay.
  6814. *
  6815. * @return {string} The overlay's ID that can be used to get or remove it.
  6816. */
  6817. Overlays.prototype.add = function(element, type, overlay) {
  6818. if (isObject(type)) {
  6819. overlay = type;
  6820. type = null;
  6821. }
  6822. if (!element.id) {
  6823. element = this._elementRegistry.get(element);
  6824. }
  6825. if (!overlay.position) {
  6826. throw new Error('must specifiy overlay position');
  6827. }
  6828. if (!overlay.html) {
  6829. throw new Error('must specifiy overlay html');
  6830. }
  6831. if (!element) {
  6832. throw new Error('invalid element specified');
  6833. }
  6834. var id = this._ids.next();
  6835. overlay = assign$1({}, this._overlayDefaults, overlay, {
  6836. id: id,
  6837. type: type,
  6838. element: element,
  6839. html: overlay.html
  6840. });
  6841. this._addOverlay(overlay);
  6842. return id;
  6843. };
  6844. /**
  6845. * Remove an overlay with the given ID or all overlays matching the given filter.
  6846. *
  6847. * @see Overlays#get for filter options.
  6848. *
  6849. * @param {OverlaysFilter} filter The filter to be used to find the overlay.
  6850. */
  6851. Overlays.prototype.remove = function(filter) {
  6852. var overlays = this.get(filter) || [];
  6853. if (!isArray$2(overlays)) {
  6854. overlays = [ overlays ];
  6855. }
  6856. var self = this;
  6857. forEach$1(overlays, function(overlay) {
  6858. var container = self._getOverlayContainer(overlay.element, true);
  6859. if (overlay) {
  6860. remove$1(overlay.html);
  6861. remove$1(overlay.htmlContainer);
  6862. delete overlay.htmlContainer;
  6863. delete overlay.element;
  6864. delete self._overlays[overlay.id];
  6865. }
  6866. if (container) {
  6867. var idx = container.overlays.indexOf(overlay);
  6868. if (idx !== -1) {
  6869. container.overlays.splice(idx, 1);
  6870. }
  6871. }
  6872. });
  6873. };
  6874. /**
  6875. * Checks whether overlays are shown.
  6876. *
  6877. * @return {boolean} Whether overlays are shown.
  6878. */
  6879. Overlays.prototype.isShown = function() {
  6880. return this._overlayRoot.style.display !== 'none';
  6881. };
  6882. /**
  6883. * Show all overlays.
  6884. */
  6885. Overlays.prototype.show = function() {
  6886. setVisible(this._overlayRoot);
  6887. };
  6888. /**
  6889. * Hide all overlays.
  6890. */
  6891. Overlays.prototype.hide = function() {
  6892. setVisible(this._overlayRoot, false);
  6893. };
  6894. /**
  6895. * Remove all overlays and their container.
  6896. */
  6897. Overlays.prototype.clear = function() {
  6898. this._overlays = {};
  6899. this._overlayContainers = [];
  6900. clear(this._overlayRoot);
  6901. };
  6902. Overlays.prototype._updateOverlayContainer = function(container) {
  6903. var element = container.element,
  6904. html = container.html;
  6905. // update container left,top according to the elements x,y coordinates
  6906. // this ensures we can attach child elements relative to this container
  6907. var x = element.x,
  6908. y = element.y;
  6909. if (element.waypoints) {
  6910. var bbox = getBBox(element);
  6911. x = bbox.x;
  6912. y = bbox.y;
  6913. }
  6914. setPosition(html, x, y);
  6915. attr(container.html, 'data-container-id', element.id);
  6916. };
  6917. Overlays.prototype._updateOverlay = function(overlay) {
  6918. var position = overlay.position,
  6919. htmlContainer = overlay.htmlContainer,
  6920. element = overlay.element;
  6921. // update overlay html relative to shape because
  6922. // it is already positioned on the element
  6923. // update relative
  6924. var left = position.left,
  6925. top = position.top;
  6926. if (position.right !== undefined) {
  6927. var width;
  6928. if (element.waypoints) {
  6929. width = getBBox(element).width;
  6930. } else {
  6931. width = element.width;
  6932. }
  6933. left = position.right * -1 + width;
  6934. }
  6935. if (position.bottom !== undefined) {
  6936. var height;
  6937. if (element.waypoints) {
  6938. height = getBBox(element).height;
  6939. } else {
  6940. height = element.height;
  6941. }
  6942. top = position.bottom * -1 + height;
  6943. }
  6944. setPosition(htmlContainer, left || 0, top || 0);
  6945. this._updateOverlayVisibilty(overlay, this._canvas.viewbox());
  6946. };
  6947. Overlays.prototype._createOverlayContainer = function(element) {
  6948. var html = domify$1('<div class="djs-overlays" />');
  6949. assign(html, { position: 'absolute' });
  6950. this._overlayRoot.appendChild(html);
  6951. var container = {
  6952. html: html,
  6953. element: element,
  6954. overlays: []
  6955. };
  6956. this._updateOverlayContainer(container);
  6957. this._overlayContainers.push(container);
  6958. return container;
  6959. };
  6960. Overlays.prototype._updateRoot = function(viewbox) {
  6961. var scale = viewbox.scale || 1;
  6962. var matrix = 'matrix(' +
  6963. [
  6964. scale,
  6965. 0,
  6966. 0,
  6967. scale,
  6968. -1 * viewbox.x * scale,
  6969. -1 * viewbox.y * scale
  6970. ].join(',') +
  6971. ')';
  6972. setTransform(this._overlayRoot, matrix);
  6973. };
  6974. Overlays.prototype._getOverlayContainer = function(element, raw) {
  6975. var container = find(this._overlayContainers, function(c) {
  6976. return c.element === element;
  6977. });
  6978. if (!container && !raw) {
  6979. return this._createOverlayContainer(element);
  6980. }
  6981. return container;
  6982. };
  6983. Overlays.prototype._addOverlay = function(overlay) {
  6984. var id = overlay.id,
  6985. element = overlay.element,
  6986. html = overlay.html,
  6987. htmlContainer,
  6988. overlayContainer;
  6989. // unwrap jquery (for those who need it)
  6990. if (html.get && html.constructor.prototype.jquery) {
  6991. html = html.get(0);
  6992. }
  6993. // create proper html elements from
  6994. // overlay HTML strings
  6995. if (isString(html)) {
  6996. html = domify$1(html);
  6997. }
  6998. overlayContainer = this._getOverlayContainer(element);
  6999. htmlContainer = domify$1('<div class="djs-overlay" data-overlay-id="' + id + '">');
  7000. assign(htmlContainer, { position: 'absolute' });
  7001. htmlContainer.appendChild(html);
  7002. if (overlay.type) {
  7003. classes(htmlContainer).add('djs-overlay-' + overlay.type);
  7004. }
  7005. var elementRoot = this._canvas.findRoot(element);
  7006. var activeRoot = this._canvas.getRootElement();
  7007. setVisible(htmlContainer, elementRoot === activeRoot);
  7008. overlay.htmlContainer = htmlContainer;
  7009. overlayContainer.overlays.push(overlay);
  7010. overlayContainer.html.appendChild(htmlContainer);
  7011. this._overlays[id] = overlay;
  7012. this._updateOverlay(overlay);
  7013. this._updateOverlayVisibilty(overlay, this._canvas.viewbox());
  7014. };
  7015. Overlays.prototype._updateOverlayVisibilty = function(overlay, viewbox) {
  7016. var show = overlay.show,
  7017. rootElement = this._canvas.findRoot(overlay.element),
  7018. minZoom = show && show.minZoom,
  7019. maxZoom = show && show.maxZoom,
  7020. htmlContainer = overlay.htmlContainer,
  7021. activeRootElement = this._canvas.getRootElement(),
  7022. visible = true;
  7023. if (rootElement !== activeRootElement) {
  7024. visible = false;
  7025. } else if (show) {
  7026. if (
  7027. (isDefined(minZoom) && minZoom > viewbox.scale) ||
  7028. (isDefined(maxZoom) && maxZoom < viewbox.scale)
  7029. ) {
  7030. visible = false;
  7031. }
  7032. }
  7033. setVisible(htmlContainer, visible);
  7034. this._updateOverlayScale(overlay, viewbox);
  7035. };
  7036. Overlays.prototype._updateOverlayScale = function(overlay, viewbox) {
  7037. var shouldScale = overlay.scale,
  7038. minScale,
  7039. maxScale,
  7040. htmlContainer = overlay.htmlContainer;
  7041. var scale, transform = '';
  7042. if (shouldScale !== true) {
  7043. if (shouldScale === false) {
  7044. minScale = 1;
  7045. maxScale = 1;
  7046. } else {
  7047. minScale = shouldScale.min;
  7048. maxScale = shouldScale.max;
  7049. }
  7050. if (isDefined(minScale) && viewbox.scale < minScale) {
  7051. scale = (1 / viewbox.scale || 1) * minScale;
  7052. }
  7053. if (isDefined(maxScale) && viewbox.scale > maxScale) {
  7054. scale = (1 / viewbox.scale || 1) * maxScale;
  7055. }
  7056. }
  7057. if (isDefined(scale)) {
  7058. transform = 'scale(' + scale + ',' + scale + ')';
  7059. }
  7060. setTransform(htmlContainer, transform);
  7061. };
  7062. Overlays.prototype._updateOverlaysVisibilty = function(viewbox) {
  7063. var self = this;
  7064. forEach$1(this._overlays, function(overlay) {
  7065. self._updateOverlayVisibilty(overlay, viewbox);
  7066. });
  7067. };
  7068. Overlays.prototype._init = function() {
  7069. var eventBus = this._eventBus;
  7070. var self = this;
  7071. // scroll/zoom integration
  7072. function updateViewbox(viewbox) {
  7073. self._updateRoot(viewbox);
  7074. self._updateOverlaysVisibilty(viewbox);
  7075. self.show();
  7076. }
  7077. eventBus.on('canvas.viewbox.changing', function(event) {
  7078. self.hide();
  7079. });
  7080. eventBus.on('canvas.viewbox.changed', function(event) {
  7081. updateViewbox(event.viewbox);
  7082. });
  7083. // remove integration
  7084. eventBus.on([ 'shape.remove', 'connection.remove' ], function(e) {
  7085. var element = e.element;
  7086. var overlays = self.get({ element: element });
  7087. forEach$1(overlays, function(o) {
  7088. self.remove(o.id);
  7089. });
  7090. var container = self._getOverlayContainer(element);
  7091. if (container) {
  7092. remove$1(container.html);
  7093. var i = self._overlayContainers.indexOf(container);
  7094. if (i !== -1) {
  7095. self._overlayContainers.splice(i, 1);
  7096. }
  7097. }
  7098. });
  7099. // move integration
  7100. eventBus.on('element.changed', LOW_PRIORITY$1, function(e) {
  7101. var element = e.element;
  7102. var container = self._getOverlayContainer(element, true);
  7103. if (container) {
  7104. forEach$1(container.overlays, function(overlay) {
  7105. self._updateOverlay(overlay);
  7106. });
  7107. self._updateOverlayContainer(container);
  7108. }
  7109. });
  7110. // marker integration, simply add them on the overlays as classes, too.
  7111. eventBus.on('element.marker.update', function(e) {
  7112. var container = self._getOverlayContainer(e.element, true);
  7113. if (container) {
  7114. classes(container.html)[e.add ? 'add' : 'remove'](e.marker);
  7115. }
  7116. });
  7117. eventBus.on('root.set', function() {
  7118. self._updateOverlaysVisibilty(self._canvas.viewbox());
  7119. });
  7120. // clear overlays with diagram
  7121. eventBus.on('diagram.clear', this.clear, this);
  7122. };
  7123. // helpers /////////////////////////////
  7124. function createRoot(parentNode) {
  7125. var root = domify$1(
  7126. '<div class="djs-overlay-container" />'
  7127. );
  7128. assign(root, {
  7129. position: 'absolute',
  7130. width: 0,
  7131. height: 0
  7132. });
  7133. parentNode.insertBefore(root, parentNode.firstChild);
  7134. return root;
  7135. }
  7136. function setPosition(el, x, y) {
  7137. assign(el, { left: x + 'px', top: y + 'px' });
  7138. }
  7139. /**
  7140. * Set element visible
  7141. *
  7142. * @param {DOMElement} el
  7143. * @param {boolean} [visible=true]
  7144. */
  7145. function setVisible(el, visible) {
  7146. el.style.display = visible === false ? 'none' : '';
  7147. }
  7148. function setTransform(el, transform) {
  7149. el.style['transform-origin'] = 'top left';
  7150. [ '', '-ms-', '-webkit-' ].forEach(function(prefix) {
  7151. el.style[prefix + 'transform'] = transform;
  7152. });
  7153. }
  7154. /**
  7155. * @type { import('didi').ModuleDeclaration }
  7156. */
  7157. var OverlaysModule = {
  7158. __init__: [ 'overlays' ],
  7159. overlays: [ 'type', Overlays ]
  7160. };
  7161. /**
  7162. * @typedef {import('../../core/Canvas').default} Canvas
  7163. * @typedef {import('../../core/ElementRegistry').default} ElementRegistry
  7164. * @typedef {import('../../core/EventBus').default} EventBus
  7165. * @typedef {import('../../core/GraphicsFactory').default} GraphicsFactory
  7166. */
  7167. /**
  7168. * Adds change support to the diagram, including
  7169. *
  7170. * <ul>
  7171. * <li>redrawing shapes and connections on change</li>
  7172. * </ul>
  7173. *
  7174. * @param {EventBus} eventBus
  7175. * @param {Canvas} canvas
  7176. * @param {ElementRegistry} elementRegistry
  7177. * @param {GraphicsFactory} graphicsFactory
  7178. */
  7179. function ChangeSupport(
  7180. eventBus, canvas, elementRegistry,
  7181. graphicsFactory) {
  7182. // redraw shapes / connections on change
  7183. eventBus.on('element.changed', function(event) {
  7184. var element = event.element;
  7185. // element might have been deleted and replaced by new element with same ID
  7186. // thus check for parent of element except for root element
  7187. if (element.parent || element === canvas.getRootElement()) {
  7188. event.gfx = elementRegistry.getGraphics(element);
  7189. }
  7190. // shape + gfx may have been deleted
  7191. if (!event.gfx) {
  7192. return;
  7193. }
  7194. eventBus.fire(getType(element) + '.changed', event);
  7195. });
  7196. eventBus.on('elements.changed', function(event) {
  7197. var elements = event.elements;
  7198. elements.forEach(function(e) {
  7199. eventBus.fire('element.changed', { element: e });
  7200. });
  7201. graphicsFactory.updateContainments(elements);
  7202. });
  7203. eventBus.on('shape.changed', function(event) {
  7204. graphicsFactory.update('shape', event.element, event.gfx);
  7205. });
  7206. eventBus.on('connection.changed', function(event) {
  7207. graphicsFactory.update('connection', event.element, event.gfx);
  7208. });
  7209. }
  7210. ChangeSupport.$inject = [
  7211. 'eventBus',
  7212. 'canvas',
  7213. 'elementRegistry',
  7214. 'graphicsFactory'
  7215. ];
  7216. /**
  7217. * @type { import('didi').ModuleDeclaration }
  7218. */
  7219. var ChangeSupportModule = {
  7220. __init__: [ 'changeSupport' ],
  7221. changeSupport: [ 'type', ChangeSupport ]
  7222. };
  7223. /**
  7224. * @typedef {import('../core/Types').ElementLike} ElementLike
  7225. * @typedef {import('../core/EventBus').default} EventBus
  7226. * @typedef {import('./CommandStack').CommandContext} CommandContext
  7227. *
  7228. * @typedef {string|string[]} Events
  7229. * @typedef { (context: CommandContext) => ElementLike[] | void } HandlerFunction
  7230. * @typedef { (context: CommandContext) => void } ComposeHandlerFunction
  7231. */
  7232. var DEFAULT_PRIORITY$1 = 1000;
  7233. /**
  7234. * A utility that can be used to plug into the command execution for
  7235. * extension and/or validation.
  7236. *
  7237. * @class
  7238. * @constructor
  7239. *
  7240. * @example
  7241. *
  7242. * ```javascript
  7243. * import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
  7244. *
  7245. * class CommandLogger extends CommandInterceptor {
  7246. * constructor(eventBus) {
  7247. * super(eventBus);
  7248. *
  7249. * this.preExecute('shape.create', (event) => {
  7250. * console.log('commandStack.shape-create.preExecute', event);
  7251. * });
  7252. * }
  7253. * ```
  7254. *
  7255. * @param {EventBus} eventBus
  7256. */
  7257. function CommandInterceptor(eventBus) {
  7258. /**
  7259. * @type {EventBus}
  7260. */
  7261. this._eventBus = eventBus;
  7262. }
  7263. CommandInterceptor.$inject = [ 'eventBus' ];
  7264. function unwrapEvent(fn, that) {
  7265. return function(event) {
  7266. return fn.call(that || null, event.context, event.command, event);
  7267. };
  7268. }
  7269. /**
  7270. * Intercept a command during one of the phases.
  7271. *
  7272. * @param {Events} [events] command(s) to intercept
  7273. * @param {string} [hook] phase to intercept
  7274. * @param {number} [priority]
  7275. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7276. * @param {boolean} [unwrap] whether the event should be unwrapped
  7277. * @param {any} [that]
  7278. */
  7279. CommandInterceptor.prototype.on = function(events, hook, priority, handlerFn, unwrap, that) {
  7280. if (isFunction(hook) || isNumber(hook)) {
  7281. that = unwrap;
  7282. unwrap = handlerFn;
  7283. handlerFn = priority;
  7284. priority = hook;
  7285. hook = null;
  7286. }
  7287. if (isFunction(priority)) {
  7288. that = unwrap;
  7289. unwrap = handlerFn;
  7290. handlerFn = priority;
  7291. priority = DEFAULT_PRIORITY$1;
  7292. }
  7293. if (isObject(unwrap)) {
  7294. that = unwrap;
  7295. unwrap = false;
  7296. }
  7297. if (!isFunction(handlerFn)) {
  7298. throw new Error('handlerFn must be a function');
  7299. }
  7300. if (!isArray$2(events)) {
  7301. events = [ events ];
  7302. }
  7303. var eventBus = this._eventBus;
  7304. forEach$1(events, function(event) {
  7305. // concat commandStack(.event)?(.hook)?
  7306. var fullEvent = [ 'commandStack', event, hook ].filter(function(e) { return e; }).join('.');
  7307. eventBus.on(fullEvent, priority, unwrap ? unwrapEvent(handlerFn, that) : handlerFn, that);
  7308. });
  7309. };
  7310. /**
  7311. * Add a <canExecute> phase of command interceptor.
  7312. *
  7313. * @param {Events} [events] command(s) to intercept
  7314. * @param {number} [priority]
  7315. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7316. * @param {boolean} [unwrap] whether the event should be unwrapped
  7317. * @param {any} [that]
  7318. */
  7319. CommandInterceptor.prototype.canExecute = createHook('canExecute');
  7320. /**
  7321. * Add a <preExecute> phase of command interceptor.
  7322. *
  7323. * @param {Events} [events] command(s) to intercept
  7324. * @param {number} [priority]
  7325. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7326. * @param {boolean} [unwrap] whether the event should be unwrapped
  7327. * @param {any} [that]
  7328. */
  7329. CommandInterceptor.prototype.preExecute = createHook('preExecute');
  7330. /**
  7331. * Add a <preExecuted> phase of command interceptor.
  7332. *
  7333. * @param {Events} [events] command(s) to intercept
  7334. * @param {number} [priority]
  7335. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7336. * @param {boolean} [unwrap] whether the event should be unwrapped
  7337. * @param {any} [that]
  7338. */
  7339. CommandInterceptor.prototype.preExecuted = createHook('preExecuted');
  7340. /**
  7341. * Add a <execute> phase of command interceptor.
  7342. *
  7343. * @param {Events} [events] command(s) to intercept
  7344. * @param {number} [priority]
  7345. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7346. * @param {boolean} [unwrap] whether the event should be unwrapped
  7347. * @param {any} [that]
  7348. */
  7349. CommandInterceptor.prototype.execute = createHook('execute');
  7350. /**
  7351. * Add a <executed> phase of command interceptor.
  7352. *
  7353. * @param {Events} [events] command(s) to intercept
  7354. * @param {number} [priority]
  7355. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7356. * @param {boolean} [unwrap] whether the event should be unwrapped
  7357. * @param {any} [that]
  7358. */
  7359. CommandInterceptor.prototype.executed = createHook('executed');
  7360. /**
  7361. * Add a <postExecute> phase of command interceptor.
  7362. *
  7363. * @param {Events} [events] command(s) to intercept
  7364. * @param {number} [priority]
  7365. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7366. * @param {boolean} [unwrap] whether the event should be unwrapped
  7367. * @param {any} [that]
  7368. */
  7369. CommandInterceptor.prototype.postExecute = createHook('postExecute');
  7370. /**
  7371. * Add a <postExecuted> phase of command interceptor.
  7372. *
  7373. * @param {Events} [events] command(s) to intercept
  7374. * @param {number} [priority]
  7375. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7376. * @param {boolean} [unwrap] whether the event should be unwrapped
  7377. * @param {any} [that]
  7378. */
  7379. CommandInterceptor.prototype.postExecuted = createHook('postExecuted');
  7380. /**
  7381. * Add a <revert> phase of command interceptor.
  7382. *
  7383. * @param {Events} [events] command(s) to intercept
  7384. * @param {number} [priority]
  7385. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7386. * @param {boolean} [unwrap] whether the event should be unwrapped
  7387. * @param {any} [that]
  7388. */
  7389. CommandInterceptor.prototype.revert = createHook('revert');
  7390. /**
  7391. * Add a <reverted> phase of command interceptor.
  7392. *
  7393. * @param {Events} [events] command(s) to intercept
  7394. * @param {number} [priority]
  7395. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7396. * @param {boolean} [unwrap] whether the event should be unwrapped
  7397. * @param {any} [that]
  7398. */
  7399. CommandInterceptor.prototype.reverted = createHook('reverted');
  7400. /*
  7401. * Add prototype methods for each phase of command execution (e.g. execute,
  7402. * revert).
  7403. *
  7404. * @param {string} hook
  7405. *
  7406. * @return { (
  7407. * events?: Events,
  7408. * priority?: number,
  7409. * handlerFn: ComposeHandlerFunction|HandlerFunction,
  7410. * unwrap?: boolean
  7411. * ) => any }
  7412. */
  7413. function createHook(hook) {
  7414. /**
  7415. * @this {CommandInterceptor}
  7416. *
  7417. * @param {Events} [events]
  7418. * @param {number} [priority]
  7419. * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
  7420. * @param {boolean} [unwrap]
  7421. * @param {any} [that]
  7422. */
  7423. const hookFn = function(events, priority, handlerFn, unwrap, that) {
  7424. if (isFunction(events) || isNumber(events)) {
  7425. that = unwrap;
  7426. unwrap = handlerFn;
  7427. handlerFn = priority;
  7428. priority = events;
  7429. events = null;
  7430. }
  7431. this.on(events, hook, priority, handlerFn, unwrap, that);
  7432. };
  7433. return hookFn;
  7434. }
  7435. /**
  7436. * @typedef {import('didi').Injector} Injector
  7437. *
  7438. * @typedef {import('../../core/Canvas').default} Canvas
  7439. */
  7440. /**
  7441. * A modeling behavior that ensures we set the correct root element
  7442. * as we undo and redo commands.
  7443. *
  7444. * @param {Canvas} canvas
  7445. * @param {Injector} injector
  7446. */
  7447. function RootElementsBehavior(canvas, injector) {
  7448. injector.invoke(CommandInterceptor, this);
  7449. this.executed(function(event) {
  7450. var context = event.context;
  7451. if (context.rootElement) {
  7452. canvas.setRootElement(context.rootElement);
  7453. } else {
  7454. context.rootElement = canvas.getRootElement();
  7455. }
  7456. });
  7457. this.revert(function(event) {
  7458. var context = event.context;
  7459. if (context.rootElement) {
  7460. canvas.setRootElement(context.rootElement);
  7461. }
  7462. });
  7463. }
  7464. e(RootElementsBehavior, CommandInterceptor);
  7465. RootElementsBehavior.$inject = [ 'canvas', 'injector' ];
  7466. /**
  7467. * @type { import('didi').ModuleDeclaration }
  7468. */
  7469. var RootElementsModule = {
  7470. __init__: [ 'rootElementsBehavior' ],
  7471. rootElementsBehavior: [ 'type', RootElementsBehavior ]
  7472. };
  7473. /**
  7474. * @param {string} str
  7475. *
  7476. * @return {string}
  7477. */
  7478. var HTML_ESCAPE_MAP = {
  7479. '&': '&amp;',
  7480. '<': '&lt;',
  7481. '>': '&gt;',
  7482. '"': '&quot;',
  7483. '\'': '&#39;'
  7484. };
  7485. /**
  7486. * @param {string} str
  7487. *
  7488. * @return {string}
  7489. */
  7490. function escapeHTML(str) {
  7491. str = '' + str;
  7492. return str && str.replace(/[&<>"']/g, function(match) {
  7493. return HTML_ESCAPE_MAP[match];
  7494. });
  7495. }
  7496. /**
  7497. * @typedef {import('../model/Types').Element} Element
  7498. * @typedef {import('../model/Types').ModdleElement} ModdleElement
  7499. */
  7500. var planeSuffix = '_plane';
  7501. /**
  7502. * Get plane ID for a primary shape.
  7503. *
  7504. * @param {Element|ModdleElement} element
  7505. *
  7506. * @return {string}
  7507. */
  7508. function getPlaneIdFromShape(element) {
  7509. var id = element.id;
  7510. if (is$1(element, 'bpmn:SubProcess')) {
  7511. return addPlaneSuffix(id);
  7512. }
  7513. return id;
  7514. }
  7515. function addPlaneSuffix(id) {
  7516. return id + planeSuffix;
  7517. }
  7518. /**
  7519. * @typedef {import('diagram-js/lib/core/Canvas').default} Canvas
  7520. * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
  7521. * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
  7522. *
  7523. * @typedef {import('../../model/Types').Element} Element
  7524. * @typedef {import('../../model/Types').Shape} Shape
  7525. */
  7526. var OPEN_CLASS = 'bjs-breadcrumbs-shown';
  7527. /**
  7528. * Adds overlays that allow switching planes on collapsed subprocesses.
  7529. *
  7530. * @param {EventBus} eventBus
  7531. * @param {ElementRegistry} elementRegistry
  7532. * @param {Canvas} canvas
  7533. */
  7534. function DrilldownBreadcrumbs(eventBus, elementRegistry, canvas) {
  7535. var breadcrumbs = domify$1('<ul class="bjs-breadcrumbs"></ul>');
  7536. var container = canvas.getContainer();
  7537. var containerClasses = classes(container);
  7538. container.appendChild(breadcrumbs);
  7539. var businessObjectParents = [];
  7540. // update breadcrumbs if name or ID of the primary shape changes
  7541. eventBus.on('element.changed', function(event) {
  7542. var shape = event.element,
  7543. businessObject = getBusinessObject(shape);
  7544. var isPresent = find(businessObjectParents, function(element) {
  7545. return element === businessObject;
  7546. });
  7547. if (!isPresent) {
  7548. return;
  7549. }
  7550. updateBreadcrumbs();
  7551. });
  7552. /**
  7553. * Updates the displayed breadcrumbs. If no element is provided, only the
  7554. * labels are updated.
  7555. *
  7556. * @param {Element} [element]
  7557. */
  7558. function updateBreadcrumbs(element) {
  7559. if (element) {
  7560. businessObjectParents = getBusinessObjectParentChain(element);
  7561. }
  7562. var path = businessObjectParents.map(function(parent) {
  7563. var title = escapeHTML(parent.name || parent.id);
  7564. var link = domify$1('<li><span class="bjs-crumb"><a title="' + title + '">' + title + '</a></span></li>');
  7565. var parentPlane = canvas.findRoot(getPlaneIdFromShape(parent)) || canvas.findRoot(parent.id);
  7566. // when the root is a collaboration, the process does not have a corresponding
  7567. // element in the elementRegisty. Instead, we search for the corresponding participant
  7568. if (!parentPlane && is$1(parent, 'bpmn:Process')) {
  7569. var participant = elementRegistry.find(function(element) {
  7570. var businessObject = getBusinessObject(element);
  7571. return businessObject && businessObject.get('processRef') && businessObject.get('processRef') === parent;
  7572. });
  7573. parentPlane = canvas.findRoot(participant.id);
  7574. }
  7575. link.addEventListener('click', function() {
  7576. canvas.setRootElement(parentPlane);
  7577. });
  7578. return link;
  7579. });
  7580. breadcrumbs.innerHTML = '';
  7581. // show breadcrumbs and expose state to .djs-container
  7582. var visible = path.length > 1;
  7583. containerClasses.toggle(OPEN_CLASS, visible);
  7584. path.forEach(function(element) {
  7585. breadcrumbs.appendChild(element);
  7586. });
  7587. }
  7588. eventBus.on('root.set', function(event) {
  7589. updateBreadcrumbs(event.element);
  7590. });
  7591. }
  7592. DrilldownBreadcrumbs.$inject = [ 'eventBus', 'elementRegistry', 'canvas' ];
  7593. // helpers //////////
  7594. /**
  7595. * Returns the parents for the element using the business object chain,
  7596. * starting with the root element.
  7597. *
  7598. * @param {Shape} child
  7599. *
  7600. * @return {Shape}
  7601. */
  7602. function getBusinessObjectParentChain(child) {
  7603. var businessObject = getBusinessObject(child);
  7604. var parents = [];
  7605. for (var element = businessObject; element; element = element.$parent) {
  7606. if (is$1(element, 'bpmn:SubProcess') || is$1(element, 'bpmn:Process')) {
  7607. parents.push(element);
  7608. }
  7609. }
  7610. return parents.reverse();
  7611. }
  7612. /**
  7613. * @typedef {import('diagram-js/lib/core/Canvas').default} Canvas
  7614. * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
  7615. */
  7616. /**
  7617. * Move collapsed subprocesses into view when drilling down.
  7618. *
  7619. * Zoom and scroll are saved in a session.
  7620. *
  7621. * @param {EventBus} eventBus
  7622. * @param {Canvas} canvas
  7623. */
  7624. function DrilldownCentering(eventBus, canvas) {
  7625. var currentRoot = null;
  7626. var positionMap = new Map();
  7627. eventBus.on('root.set', function(event) {
  7628. var newRoot = event.element;
  7629. var currentViewbox = canvas.viewbox();
  7630. var storedViewbox = positionMap.get(newRoot);
  7631. positionMap.set(currentRoot, {
  7632. x: currentViewbox.x,
  7633. y: currentViewbox.y,
  7634. zoom: currentViewbox.scale
  7635. });
  7636. currentRoot = newRoot;
  7637. // current root was replaced with a collaboration, we don't update the viewbox
  7638. if (is$1(newRoot, 'bpmn:Collaboration') && !storedViewbox) {
  7639. return;
  7640. }
  7641. storedViewbox = storedViewbox || { x: 0, y: 0, zoom: 1 };
  7642. var dx = (currentViewbox.x - storedViewbox.x) * currentViewbox.scale,
  7643. dy = (currentViewbox.y - storedViewbox.y) * currentViewbox.scale;
  7644. if (dx !== 0 || dy !== 0) {
  7645. canvas.scroll({
  7646. dx: dx,
  7647. dy: dy
  7648. });
  7649. }
  7650. if (storedViewbox.zoom !== currentViewbox.scale) {
  7651. canvas.zoom(storedViewbox.zoom, { x: 0, y: 0 });
  7652. }
  7653. });
  7654. eventBus.on('diagram.clear', function() {
  7655. positionMap.clear();
  7656. currentRoot = null;
  7657. });
  7658. }
  7659. DrilldownCentering.$inject = [ 'eventBus', 'canvas' ];
  7660. /**
  7661. * ES5 Map implementation. Works.
  7662. */
  7663. function Map() {
  7664. this._entries = [];
  7665. this.set = function(key, value) {
  7666. var found = false;
  7667. for (var k in this._entries) {
  7668. if (this._entries[k][0] === key) {
  7669. this._entries[k][1] = value;
  7670. found = true;
  7671. break;
  7672. }
  7673. }
  7674. if (!found) {
  7675. this._entries.push([ key, value ]);
  7676. }
  7677. };
  7678. this.get = function(key) {
  7679. for (var k in this._entries) {
  7680. if (this._entries[k][0] === key) {
  7681. return this._entries[k][1];
  7682. }
  7683. }
  7684. return null;
  7685. };
  7686. this.clear = function() {
  7687. this._entries.length = 0;
  7688. };
  7689. this.remove = function(key) {
  7690. var idx = -1;
  7691. for (var k in this._entries) {
  7692. if (this._entries[k][0] === key) {
  7693. idx = k;
  7694. break;
  7695. }
  7696. }
  7697. if (idx !== -1) {
  7698. this._entries.splice(idx, 1);
  7699. }
  7700. };
  7701. }
  7702. /**
  7703. * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
  7704. * @typedef {import('../../model/Types').Moddle} Moddle
  7705. *
  7706. * @typedef {import('../../model/Types').Element} Element
  7707. * @typedef {import('../../model/Types').Shape} Shape
  7708. *
  7709. * @typedef {import('diagram-js/lib/core/Canvas').CanvasPlane} CanvasPlane
  7710. *
  7711. * @typedef {import('diagram-js/lib/util/Types').Rect} Rect
  7712. */
  7713. var DEFAULT_POSITION = {
  7714. x: 180,
  7715. y: 160
  7716. };
  7717. /**
  7718. * Hook into `import.render.start` and create new planes for diagrams with
  7719. * collapsed subprocesses and all DI elements on the same plane.
  7720. *
  7721. * @param {EventBus} eventBus
  7722. * @param {Moddle} moddle
  7723. */
  7724. function SubprocessCompatibility(eventBus, moddle) {
  7725. this._eventBus = eventBus;
  7726. this._moddle = moddle;
  7727. var self = this;
  7728. eventBus.on('import.render.start', 1500, function(e, context) {
  7729. self._handleImport(context.definitions);
  7730. });
  7731. }
  7732. /**
  7733. * @param {ModdleElement} definitions
  7734. */
  7735. SubprocessCompatibility.prototype._handleImport = function(definitions) {
  7736. if (!definitions.diagrams) {
  7737. return;
  7738. }
  7739. var self = this;
  7740. this._definitions = definitions;
  7741. this._processToDiagramMap = {};
  7742. definitions.diagrams.forEach(function(diagram) {
  7743. if (!diagram.plane || !diagram.plane.bpmnElement) {
  7744. return;
  7745. }
  7746. self._processToDiagramMap[diagram.plane.bpmnElement.id] = diagram;
  7747. });
  7748. var newDiagrams = [];
  7749. definitions.diagrams.forEach(function(diagram) {
  7750. var createdDiagrams = self._createNewDiagrams(diagram.plane);
  7751. Array.prototype.push.apply(newDiagrams, createdDiagrams);
  7752. });
  7753. newDiagrams.forEach(function(diagram) {
  7754. self._movePlaneElementsToOrigin(diagram.plane);
  7755. });
  7756. };
  7757. /**
  7758. * Moves all DI elements from collapsed subprocesses to a new plane.
  7759. *
  7760. * @param {CanvasPlane} plane
  7761. *
  7762. * @return {ModdleElement[]} new diagrams created for the collapsed subprocesses
  7763. */
  7764. SubprocessCompatibility.prototype._createNewDiagrams = function(plane) {
  7765. var self = this;
  7766. var collapsedElements = [];
  7767. var elementsToMove = [];
  7768. plane.get('planeElement').forEach(function(diElement) {
  7769. var businessObject = diElement.bpmnElement;
  7770. if (!businessObject) {
  7771. return;
  7772. }
  7773. var parent = businessObject.$parent;
  7774. if (is$1(businessObject, 'bpmn:SubProcess') && !diElement.isExpanded) {
  7775. collapsedElements.push(businessObject);
  7776. }
  7777. if (shouldMoveToPlane(businessObject, plane)) {
  7778. // don't change the array while we iterate over it
  7779. elementsToMove.push({ diElement: diElement, parent: parent });
  7780. }
  7781. });
  7782. var newDiagrams = [];
  7783. // create new planes for all collapsed subprocesses, even when they are empty
  7784. collapsedElements.forEach(function(element) {
  7785. if (!self._processToDiagramMap[ element.id ]) {
  7786. var diagram = self._createDiagram(element);
  7787. self._processToDiagramMap[element.id] = diagram;
  7788. newDiagrams.push(diagram);
  7789. }
  7790. });
  7791. elementsToMove.forEach(function(element) {
  7792. var diElement = element.diElement;
  7793. var parent = element.parent;
  7794. // parent is expanded, get nearest collapsed parent
  7795. while (parent && collapsedElements.indexOf(parent) === -1) {
  7796. parent = parent.$parent;
  7797. }
  7798. // false positive, all parents are expanded
  7799. if (!parent) {
  7800. return;
  7801. }
  7802. var diagram = self._processToDiagramMap[ parent.id ];
  7803. self._moveToDiPlane(diElement, diagram.plane);
  7804. });
  7805. return newDiagrams;
  7806. };
  7807. /**
  7808. * @param {CanvasPlane} plane
  7809. */
  7810. SubprocessCompatibility.prototype._movePlaneElementsToOrigin = function(plane) {
  7811. var elements = plane.get('planeElement');
  7812. // get bounding box of all elements
  7813. var planeBounds = getPlaneBounds(plane);
  7814. var offset = {
  7815. x: planeBounds.x - DEFAULT_POSITION.x,
  7816. y: planeBounds.y - DEFAULT_POSITION.y
  7817. };
  7818. elements.forEach(function(diElement) {
  7819. if (diElement.waypoint) {
  7820. diElement.waypoint.forEach(function(waypoint) {
  7821. waypoint.x = waypoint.x - offset.x;
  7822. waypoint.y = waypoint.y - offset.y;
  7823. });
  7824. } else if (diElement.bounds) {
  7825. diElement.bounds.x = diElement.bounds.x - offset.x;
  7826. diElement.bounds.y = diElement.bounds.y - offset.y;
  7827. }
  7828. });
  7829. };
  7830. /**
  7831. * @param {ModdleElement} diElement
  7832. * @param {CanvasPlane} newPlane
  7833. */
  7834. SubprocessCompatibility.prototype._moveToDiPlane = function(diElement, newPlane) {
  7835. var containingDiagram = findRootDiagram(diElement);
  7836. // remove DI from old Plane and add it to the new one
  7837. var parentPlaneElement = containingDiagram.plane.get('planeElement');
  7838. parentPlaneElement.splice(parentPlaneElement.indexOf(diElement), 1);
  7839. newPlane.get('planeElement').push(diElement);
  7840. };
  7841. /**
  7842. * @param {ModdleElement} businessObject
  7843. *
  7844. * @return {ModdleElement}
  7845. */
  7846. SubprocessCompatibility.prototype._createDiagram = function(businessObject) {
  7847. var plane = this._moddle.create('bpmndi:BPMNPlane', {
  7848. bpmnElement: businessObject
  7849. });
  7850. var diagram = this._moddle.create('bpmndi:BPMNDiagram', {
  7851. plane: plane
  7852. });
  7853. plane.$parent = diagram;
  7854. plane.bpmnElement = businessObject;
  7855. diagram.$parent = this._definitions;
  7856. this._definitions.diagrams.push(diagram);
  7857. return diagram;
  7858. };
  7859. SubprocessCompatibility.$inject = [ 'eventBus', 'moddle' ];
  7860. // helpers //////////
  7861. function findRootDiagram(element) {
  7862. if (is$1(element, 'bpmndi:BPMNDiagram')) {
  7863. return element;
  7864. } else {
  7865. return findRootDiagram(element.$parent);
  7866. }
  7867. }
  7868. /**
  7869. * @param {CanvasPlane} plane
  7870. *
  7871. * @return {Rect}
  7872. */
  7873. function getPlaneBounds(plane) {
  7874. var planeTrbl = {
  7875. top: Infinity,
  7876. right: -Infinity,
  7877. bottom: -Infinity,
  7878. left: Infinity
  7879. };
  7880. plane.planeElement.forEach(function(element) {
  7881. if (!element.bounds) {
  7882. return;
  7883. }
  7884. var trbl = asTRBL(element.bounds);
  7885. planeTrbl.top = Math.min(trbl.top, planeTrbl.top);
  7886. planeTrbl.left = Math.min(trbl.left, planeTrbl.left);
  7887. });
  7888. return asBounds(planeTrbl);
  7889. }
  7890. /**
  7891. * @param {ModdleElement} businessObject
  7892. * @param {CanvasPlane} plane
  7893. *
  7894. * @return {boolean}
  7895. */
  7896. function shouldMoveToPlane(businessObject, plane) {
  7897. var parent = businessObject.$parent;
  7898. // don't move elements that are already on the plane
  7899. if (!is$1(parent, 'bpmn:SubProcess') || parent === plane.bpmnElement) {
  7900. return false;
  7901. }
  7902. // dataAssociations are children of the subprocess but rendered on process level
  7903. // cf. https://github.com/bpmn-io/bpmn-js/issues/1619
  7904. if (isAny(businessObject, [ 'bpmn:DataInputAssociation', 'bpmn:DataOutputAssociation' ])) {
  7905. return false;
  7906. }
  7907. return true;
  7908. }
  7909. /**
  7910. * @typedef {import('diagram-js/lib/core/Canvas').default} Canvas
  7911. * @typedef {import('diagram-js/lib/core/ElementRegistry').default} ElementRegistry
  7912. * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
  7913. * @typedef {import('diagram-js/lib/features/overlays/Overlays').default} Overlays
  7914. *
  7915. * @typedef {import('../../model/Types').Element} Element
  7916. * @typedef {import('../../model/Types').Parent} Parent
  7917. * @typedef {import('../../model/Types').Shape} Shape
  7918. */
  7919. var LOW_PRIORITY = 250;
  7920. var ARROW_DOWN_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.81801948,3.50735931 L10.4996894,9.1896894 L10.5,4 L12,4 L12,12 L4,12 L4,10.5 L9.6896894,10.4996894 L3.75735931,4.56801948 C3.46446609,4.27512627 3.46446609,3.80025253 3.75735931,3.50735931 C4.05025253,3.21446609 4.52512627,3.21446609 4.81801948,3.50735931 Z"/></svg>';
  7921. var EMPTY_MARKER = 'bjs-drilldown-empty';
  7922. /**
  7923. * @param {Canvas} canvas
  7924. * @param {EventBus} eventBus
  7925. * @param {ElementRegistry} elementRegistry
  7926. * @param {Overlays} overlays
  7927. */
  7928. function DrilldownOverlayBehavior(
  7929. canvas, eventBus, elementRegistry, overlays
  7930. ) {
  7931. CommandInterceptor.call(this, eventBus);
  7932. this._canvas = canvas;
  7933. this._eventBus = eventBus;
  7934. this._elementRegistry = elementRegistry;
  7935. this._overlays = overlays;
  7936. var self = this;
  7937. this.executed('shape.toggleCollapse', LOW_PRIORITY, function(context) {
  7938. var shape = context.shape;
  7939. // Add overlay to the collapsed shape
  7940. if (self._canDrillDown(shape)) {
  7941. self._addOverlay(shape);
  7942. } else {
  7943. self._removeOverlay(shape);
  7944. }
  7945. }, true);
  7946. this.reverted('shape.toggleCollapse', LOW_PRIORITY, function(context) {
  7947. var shape = context.shape;
  7948. // Add overlay to the collapsed shape
  7949. if (self._canDrillDown(shape)) {
  7950. self._addOverlay(shape);
  7951. } else {
  7952. self._removeOverlay(shape);
  7953. }
  7954. }, true);
  7955. this.executed([ 'shape.create', 'shape.move', 'shape.delete' ], LOW_PRIORITY,
  7956. function(context) {
  7957. var oldParent = context.oldParent,
  7958. newParent = context.newParent || context.parent,
  7959. shape = context.shape;
  7960. // Add overlay to the collapsed shape
  7961. if (self._canDrillDown(shape)) {
  7962. self._addOverlay(shape);
  7963. }
  7964. self._updateDrilldownOverlay(oldParent);
  7965. self._updateDrilldownOverlay(newParent);
  7966. self._updateDrilldownOverlay(shape);
  7967. }, true);
  7968. this.reverted([ 'shape.create', 'shape.move', 'shape.delete' ], LOW_PRIORITY,
  7969. function(context) {
  7970. var oldParent = context.oldParent,
  7971. newParent = context.newParent || context.parent,
  7972. shape = context.shape;
  7973. // Add overlay to the collapsed shape
  7974. if (self._canDrillDown(shape)) {
  7975. self._addOverlay(shape);
  7976. }
  7977. self._updateDrilldownOverlay(oldParent);
  7978. self._updateDrilldownOverlay(newParent);
  7979. self._updateDrilldownOverlay(shape);
  7980. }, true);
  7981. eventBus.on('import.render.complete', function() {
  7982. elementRegistry.filter(function(e) {
  7983. return self._canDrillDown(e);
  7984. }).map(function(el) {
  7985. self._addOverlay(el);
  7986. });
  7987. });
  7988. }
  7989. e(DrilldownOverlayBehavior, CommandInterceptor);
  7990. /**
  7991. * @param {Shape} shape
  7992. */
  7993. DrilldownOverlayBehavior.prototype._updateDrilldownOverlay = function(shape) {
  7994. var canvas = this._canvas;
  7995. if (!shape) {
  7996. return;
  7997. }
  7998. var root = canvas.findRoot(shape);
  7999. if (root) {
  8000. this._updateOverlayVisibility(root);
  8001. }
  8002. };
  8003. /**
  8004. * @param {Element} element
  8005. *
  8006. * @return {boolean}
  8007. */
  8008. DrilldownOverlayBehavior.prototype._canDrillDown = function(element) {
  8009. var canvas = this._canvas;
  8010. return is$1(element, 'bpmn:SubProcess') && canvas.findRoot(getPlaneIdFromShape(element));
  8011. };
  8012. /**
  8013. * Update the visibility of the drilldown overlay. If the plane has no elements,
  8014. * the drilldown will only be shown when the element is selected.
  8015. *
  8016. * @param {Parent} element The collapsed root or shape.
  8017. */
  8018. DrilldownOverlayBehavior.prototype._updateOverlayVisibility = function(element) {
  8019. var overlays = this._overlays;
  8020. var businessObject = getBusinessObject(element);
  8021. var overlay = overlays.get({ element: businessObject.id, type: 'drilldown' })[0];
  8022. if (!overlay) {
  8023. return;
  8024. }
  8025. var hasFlowElements = businessObject
  8026. && businessObject.get('flowElements')
  8027. && businessObject.get('flowElements').length;
  8028. classes(overlay.html).toggle(EMPTY_MARKER, !hasFlowElements);
  8029. };
  8030. /**
  8031. * Add a drilldown button to the given element assuming the plane has the same
  8032. * ID as the element.
  8033. *
  8034. * @param {Shape} element The collapsed shape.
  8035. */
  8036. DrilldownOverlayBehavior.prototype._addOverlay = function(element) {
  8037. var canvas = this._canvas,
  8038. overlays = this._overlays;
  8039. var existingOverlays = overlays.get({ element: element, type: 'drilldown' });
  8040. if (existingOverlays.length) {
  8041. this._removeOverlay(element);
  8042. }
  8043. var button = domify$1('<button class="bjs-drilldown">' + ARROW_DOWN_SVG + '</button>');
  8044. button.addEventListener('click', function() {
  8045. canvas.setRootElement(canvas.findRoot(getPlaneIdFromShape(element)));
  8046. });
  8047. overlays.add(element, 'drilldown', {
  8048. position: {
  8049. bottom: -7,
  8050. right: -8
  8051. },
  8052. html: button
  8053. });
  8054. this._updateOverlayVisibility(element);
  8055. };
  8056. DrilldownOverlayBehavior.prototype._removeOverlay = function(element) {
  8057. var overlays = this._overlays;
  8058. overlays.remove({
  8059. element: element,
  8060. type: 'drilldown'
  8061. });
  8062. };
  8063. DrilldownOverlayBehavior.$inject = [
  8064. 'canvas',
  8065. 'eventBus',
  8066. 'elementRegistry',
  8067. 'overlays'
  8068. ];
  8069. var DrilldownModdule = {
  8070. __depends__: [ OverlaysModule, ChangeSupportModule, RootElementsModule ],
  8071. __init__: [ 'drilldownBreadcrumbs', 'drilldownOverlayBehavior', 'drilldownCentering', 'subprocessCompatibility' ],
  8072. drilldownBreadcrumbs: [ 'type', DrilldownBreadcrumbs ],
  8073. drilldownCentering: [ 'type', DrilldownCentering ],
  8074. drilldownOverlayBehavior: [ 'type', DrilldownOverlayBehavior ],
  8075. subprocessCompatibility: [ 'type', SubprocessCompatibility ]
  8076. };
  8077. const CLASS_PATTERN = /^class[ {]/;
  8078. /**
  8079. * @param {function} fn
  8080. *
  8081. * @return {boolean}
  8082. */
  8083. function isClass(fn) {
  8084. return CLASS_PATTERN.test(fn.toString());
  8085. }
  8086. /**
  8087. * @param {any} obj
  8088. *
  8089. * @return {boolean}
  8090. */
  8091. function isArray(obj) {
  8092. return Array.isArray(obj);
  8093. }
  8094. /**
  8095. * @param {any} obj
  8096. * @param {string} prop
  8097. *
  8098. * @return {boolean}
  8099. */
  8100. function hasOwnProp(obj, prop) {
  8101. return Object.prototype.hasOwnProperty.call(obj, prop);
  8102. }
  8103. /**
  8104. * @typedef {import('./index.js').InjectAnnotated } InjectAnnotated
  8105. */
  8106. /**
  8107. * @template T
  8108. *
  8109. * @params {[...string[], T] | ...string[], T} args
  8110. *
  8111. * @return {T & InjectAnnotated}
  8112. */
  8113. function annotate(...args) {
  8114. if (args.length === 1 && isArray(args[0])) {
  8115. args = args[0];
  8116. }
  8117. args = [ ...args ];
  8118. const fn = args.pop();
  8119. fn.$inject = args;
  8120. return fn;
  8121. }
  8122. // Current limitations:
  8123. // - can't put into "function arg" comments
  8124. // function /* (no parenthesis like this) */ (){}
  8125. // function abc( /* xx (no parenthesis like this) */ a, b) {}
  8126. //
  8127. // Just put the comment before function or inside:
  8128. // /* (((this is fine))) */ function(a, b) {}
  8129. // function abc(a) { /* (((this is fine))) */}
  8130. //
  8131. // - can't reliably auto-annotate constructor; we'll match the
  8132. // first constructor(...) pattern found which may be the one
  8133. // of a nested class, too.
  8134. const CONSTRUCTOR_ARGS = /constructor\s*[^(]*\(\s*([^)]*)\)/m;
  8135. const FN_ARGS = /^(?:async\s+)?(?:function\s*[^(]*)?(?:\(\s*([^)]*)\)|(\w+))/m;
  8136. const FN_ARG = /\/\*([^*]*)\*\//m;
  8137. /**
  8138. * @param {unknown} fn
  8139. *
  8140. * @return {string[]}
  8141. */
  8142. function parseAnnotations(fn) {
  8143. if (typeof fn !== 'function') {
  8144. throw new Error(`Cannot annotate "${fn}". Expected a function!`);
  8145. }
  8146. const match = fn.toString().match(isClass(fn) ? CONSTRUCTOR_ARGS : FN_ARGS);
  8147. // may parse class without constructor
  8148. if (!match) {
  8149. return [];
  8150. }
  8151. const args = match[1] || match[2];
  8152. return args && args.split(',').map(arg => {
  8153. const argMatch = arg.match(FN_ARG);
  8154. return (argMatch && argMatch[1] || arg).trim();
  8155. }) || [];
  8156. }
  8157. /**
  8158. * @typedef { import('./index.js').ModuleDeclaration } ModuleDeclaration
  8159. * @typedef { import('./index.js').ModuleDefinition } ModuleDefinition
  8160. * @typedef { import('./index.js').InjectorContext } InjectorContext
  8161. */
  8162. /**
  8163. * Create a new injector with the given modules.
  8164. *
  8165. * @param {ModuleDefinition[]} modules
  8166. * @param {InjectorContext} [parent]
  8167. */
  8168. function Injector(modules, parent) {
  8169. parent = parent || {
  8170. get: function(name, strict) {
  8171. currentlyResolving.push(name);
  8172. if (strict === false) {
  8173. return null;
  8174. } else {
  8175. throw error(`No provider for "${ name }"!`);
  8176. }
  8177. }
  8178. };
  8179. const currentlyResolving = [];
  8180. const providers = this._providers = Object.create(parent._providers || null);
  8181. const instances = this._instances = Object.create(null);
  8182. const self = instances.injector = this;
  8183. const error = function(msg) {
  8184. const stack = currentlyResolving.join(' -> ');
  8185. currentlyResolving.length = 0;
  8186. return new Error(stack ? `${ msg } (Resolving: ${ stack })` : msg);
  8187. };
  8188. /**
  8189. * Return a named service.
  8190. *
  8191. * @param {string} name
  8192. * @param {boolean} [strict=true] if false, resolve missing services to null
  8193. *
  8194. * @return {any}
  8195. */
  8196. function get(name, strict) {
  8197. if (!providers[name] && name.indexOf('.') !== -1) {
  8198. const parts = name.split('.');
  8199. let pivot = get(parts.shift());
  8200. while (parts.length) {
  8201. pivot = pivot[parts.shift()];
  8202. }
  8203. return pivot;
  8204. }
  8205. if (hasOwnProp(instances, name)) {
  8206. return instances[name];
  8207. }
  8208. if (hasOwnProp(providers, name)) {
  8209. if (currentlyResolving.indexOf(name) !== -1) {
  8210. currentlyResolving.push(name);
  8211. throw error('Cannot resolve circular dependency!');
  8212. }
  8213. currentlyResolving.push(name);
  8214. instances[name] = providers[name][0](providers[name][1]);
  8215. currentlyResolving.pop();
  8216. return instances[name];
  8217. }
  8218. return parent.get(name, strict);
  8219. }
  8220. function fnDef(fn, locals) {
  8221. if (typeof locals === 'undefined') {
  8222. locals = {};
  8223. }
  8224. if (typeof fn !== 'function') {
  8225. if (isArray(fn)) {
  8226. fn = annotate(fn.slice());
  8227. } else {
  8228. throw error(`Cannot invoke "${ fn }". Expected a function!`);
  8229. }
  8230. }
  8231. const inject = fn.$inject || parseAnnotations(fn);
  8232. const dependencies = inject.map(dep => {
  8233. if (hasOwnProp(locals, dep)) {
  8234. return locals[dep];
  8235. } else {
  8236. return get(dep);
  8237. }
  8238. });
  8239. return {
  8240. fn: fn,
  8241. dependencies: dependencies
  8242. };
  8243. }
  8244. /**
  8245. * Instantiate the given type, injecting dependencies.
  8246. *
  8247. * @template T
  8248. *
  8249. * @param { Function | [...string[], Function ]} type
  8250. *
  8251. * @return T
  8252. */
  8253. function instantiate(type) {
  8254. const {
  8255. fn,
  8256. dependencies
  8257. } = fnDef(type);
  8258. // instantiate var args constructor
  8259. const Constructor = Function.prototype.bind.apply(fn, [ null ].concat(dependencies));
  8260. return new Constructor();
  8261. }
  8262. /**
  8263. * Invoke the given function, injecting dependencies. Return the result.
  8264. *
  8265. * @template T
  8266. *
  8267. * @param { Function | [...string[], Function ]} func
  8268. * @param { Object } [context]
  8269. * @param { Object } [locals]
  8270. *
  8271. * @return {T} invocation result
  8272. */
  8273. function invoke(func, context, locals) {
  8274. const {
  8275. fn,
  8276. dependencies
  8277. } = fnDef(func, locals);
  8278. return fn.apply(context, dependencies);
  8279. }
  8280. /**
  8281. * @param {Injector} childInjector
  8282. *
  8283. * @return {Function}
  8284. */
  8285. function createPrivateInjectorFactory(childInjector) {
  8286. return annotate(key => childInjector.get(key));
  8287. }
  8288. /**
  8289. * @param {ModuleDefinition[]} modules
  8290. * @param {string[]} [forceNewInstances]
  8291. *
  8292. * @return {Injector}
  8293. */
  8294. function createChild(modules, forceNewInstances) {
  8295. if (forceNewInstances && forceNewInstances.length) {
  8296. const fromParentModule = Object.create(null);
  8297. const matchedScopes = Object.create(null);
  8298. const privateInjectorsCache = [];
  8299. const privateChildInjectors = [];
  8300. const privateChildFactories = [];
  8301. let provider;
  8302. let cacheIdx;
  8303. let privateChildInjector;
  8304. let privateChildInjectorFactory;
  8305. for (let name in providers) {
  8306. provider = providers[name];
  8307. if (forceNewInstances.indexOf(name) !== -1) {
  8308. if (provider[2] === 'private') {
  8309. cacheIdx = privateInjectorsCache.indexOf(provider[3]);
  8310. if (cacheIdx === -1) {
  8311. privateChildInjector = provider[3].createChild([], forceNewInstances);
  8312. privateChildInjectorFactory = createPrivateInjectorFactory(privateChildInjector);
  8313. privateInjectorsCache.push(provider[3]);
  8314. privateChildInjectors.push(privateChildInjector);
  8315. privateChildFactories.push(privateChildInjectorFactory);
  8316. fromParentModule[name] = [ privateChildInjectorFactory, name, 'private', privateChildInjector ];
  8317. } else {
  8318. fromParentModule[name] = [ privateChildFactories[cacheIdx], name, 'private', privateChildInjectors[cacheIdx] ];
  8319. }
  8320. } else {
  8321. fromParentModule[name] = [ provider[2], provider[1] ];
  8322. }
  8323. matchedScopes[name] = true;
  8324. }
  8325. if ((provider[2] === 'factory' || provider[2] === 'type') && provider[1].$scope) {
  8326. /* jshint -W083 */
  8327. forceNewInstances.forEach(scope => {
  8328. if (provider[1].$scope.indexOf(scope) !== -1) {
  8329. fromParentModule[name] = [ provider[2], provider[1] ];
  8330. matchedScopes[scope] = true;
  8331. }
  8332. });
  8333. }
  8334. }
  8335. forceNewInstances.forEach(scope => {
  8336. if (!matchedScopes[scope]) {
  8337. throw new Error('No provider for "' + scope + '". Cannot use provider from the parent!');
  8338. }
  8339. });
  8340. modules.unshift(fromParentModule);
  8341. }
  8342. return new Injector(modules, self);
  8343. }
  8344. const factoryMap = {
  8345. factory: invoke,
  8346. type: instantiate,
  8347. value: function(value) {
  8348. return value;
  8349. }
  8350. };
  8351. /**
  8352. * @param {ModuleDefinition} moduleDefinition
  8353. * @param {Injector} injector
  8354. */
  8355. function createInitializer(moduleDefinition, injector) {
  8356. const initializers = moduleDefinition.__init__ || [];
  8357. return function() {
  8358. initializers.forEach(initializer => {
  8359. // eagerly resolve component (fn or string)
  8360. if (typeof initializer === 'string') {
  8361. injector.get(initializer);
  8362. } else {
  8363. injector.invoke(initializer);
  8364. }
  8365. });
  8366. };
  8367. }
  8368. /**
  8369. * @param {ModuleDefinition} moduleDefinition
  8370. */
  8371. function loadModule(moduleDefinition) {
  8372. const moduleExports = moduleDefinition.__exports__;
  8373. // private module
  8374. if (moduleExports) {
  8375. const nestedModules = moduleDefinition.__modules__;
  8376. const clonedModule = Object.keys(moduleDefinition).reduce((clonedModule, key) => {
  8377. if (key !== '__exports__' && key !== '__modules__' && key !== '__init__' && key !== '__depends__') {
  8378. clonedModule[key] = moduleDefinition[key];
  8379. }
  8380. return clonedModule;
  8381. }, Object.create(null));
  8382. const childModules = (nestedModules || []).concat(clonedModule);
  8383. const privateInjector = createChild(childModules);
  8384. const getFromPrivateInjector = annotate(function(key) {
  8385. return privateInjector.get(key);
  8386. });
  8387. moduleExports.forEach(function(key) {
  8388. providers[key] = [ getFromPrivateInjector, key, 'private', privateInjector ];
  8389. });
  8390. // ensure child injector initializes
  8391. const initializers = (moduleDefinition.__init__ || []).slice();
  8392. initializers.unshift(function() {
  8393. privateInjector.init();
  8394. });
  8395. moduleDefinition = Object.assign({}, moduleDefinition, {
  8396. __init__: initializers
  8397. });
  8398. return createInitializer(moduleDefinition, privateInjector);
  8399. }
  8400. // normal module
  8401. Object.keys(moduleDefinition).forEach(function(key) {
  8402. if (key === '__init__' || key === '__depends__') {
  8403. return;
  8404. }
  8405. if (moduleDefinition[key][2] === 'private') {
  8406. providers[key] = moduleDefinition[key];
  8407. return;
  8408. }
  8409. const type = moduleDefinition[key][0];
  8410. const value = moduleDefinition[key][1];
  8411. providers[key] = [ factoryMap[type], arrayUnwrap(type, value), type ];
  8412. });
  8413. return createInitializer(moduleDefinition, self);
  8414. }
  8415. /**
  8416. * @param {ModuleDefinition[]} moduleDefinitions
  8417. * @param {ModuleDefinition} moduleDefinition
  8418. *
  8419. * @return {ModuleDefinition[]}
  8420. */
  8421. function resolveDependencies(moduleDefinitions, moduleDefinition) {
  8422. if (moduleDefinitions.indexOf(moduleDefinition) !== -1) {
  8423. return moduleDefinitions;
  8424. }
  8425. moduleDefinitions = (moduleDefinition.__depends__ || []).reduce(resolveDependencies, moduleDefinitions);
  8426. if (moduleDefinitions.indexOf(moduleDefinition) !== -1) {
  8427. return moduleDefinitions;
  8428. }
  8429. return moduleDefinitions.concat(moduleDefinition);
  8430. }
  8431. /**
  8432. * @param {ModuleDefinition[]} moduleDefinitions
  8433. *
  8434. * @return { () => void } initializerFn
  8435. */
  8436. function bootstrap(moduleDefinitions) {
  8437. const initializers = moduleDefinitions
  8438. .reduce(resolveDependencies, [])
  8439. .map(loadModule);
  8440. let initialized = false;
  8441. return function() {
  8442. if (initialized) {
  8443. return;
  8444. }
  8445. initialized = true;
  8446. initializers.forEach(initializer => initializer());
  8447. };
  8448. }
  8449. // public API
  8450. this.get = get;
  8451. this.invoke = invoke;
  8452. this.instantiate = instantiate;
  8453. this.createChild = createChild;
  8454. // setup
  8455. this.init = bootstrap(modules);
  8456. }
  8457. // helpers ///////////////
  8458. function arrayUnwrap(type, value) {
  8459. if (type !== 'value' && isArray(value)) {
  8460. value = annotate(value.slice());
  8461. }
  8462. return value;
  8463. }
  8464. /**
  8465. * @typedef {import('../core/EventBus').default} EventBus
  8466. * @typedef {import('./Styles').default} Styles
  8467. */
  8468. // apply default renderer with lowest possible priority
  8469. // so that it only kicks in if noone else could render
  8470. var DEFAULT_RENDER_PRIORITY = 1;
  8471. /**
  8472. * The default renderer used for shapes and connections.
  8473. *
  8474. * @param {EventBus} eventBus
  8475. * @param {Styles} styles
  8476. */
  8477. function DefaultRenderer(eventBus, styles) {
  8478. BaseRenderer.call(this, eventBus, DEFAULT_RENDER_PRIORITY);
  8479. this.CONNECTION_STYLE = styles.style([ 'no-fill' ], { strokeWidth: 5, stroke: 'fuchsia' });
  8480. this.SHAPE_STYLE = styles.style({ fill: 'white', stroke: 'fuchsia', strokeWidth: 2 });
  8481. this.FRAME_STYLE = styles.style([ 'no-fill' ], { stroke: 'fuchsia', strokeDasharray: 4, strokeWidth: 2 });
  8482. }
  8483. e(DefaultRenderer, BaseRenderer);
  8484. /**
  8485. * @private
  8486. */
  8487. DefaultRenderer.prototype.canRender = function() {
  8488. return true;
  8489. };
  8490. /**
  8491. * @private
  8492. */
  8493. DefaultRenderer.prototype.drawShape = function drawShape(visuals, element, attrs) {
  8494. var rect = create$1('rect');
  8495. attr$1(rect, {
  8496. x: 0,
  8497. y: 0,
  8498. width: element.width || 0,
  8499. height: element.height || 0
  8500. });
  8501. if (isFrameElement(element)) {
  8502. attr$1(rect, assign$1({}, this.FRAME_STYLE, attrs || {}));
  8503. } else {
  8504. attr$1(rect, assign$1({}, this.SHAPE_STYLE, attrs || {}));
  8505. }
  8506. append(visuals, rect);
  8507. return rect;
  8508. };
  8509. /**
  8510. * @private
  8511. */
  8512. DefaultRenderer.prototype.drawConnection = function drawConnection(visuals, connection, attrs) {
  8513. var line = createLine(connection.waypoints, assign$1({}, this.CONNECTION_STYLE, attrs || {}));
  8514. append(visuals, line);
  8515. return line;
  8516. };
  8517. /**
  8518. * @private
  8519. */
  8520. DefaultRenderer.prototype.getShapePath = function getShapePath(shape) {
  8521. var x = shape.x,
  8522. y = shape.y,
  8523. width = shape.width,
  8524. height = shape.height;
  8525. var shapePath = [
  8526. [ 'M', x, y ],
  8527. [ 'l', width, 0 ],
  8528. [ 'l', 0, height ],
  8529. [ 'l', -width, 0 ],
  8530. [ 'z' ]
  8531. ];
  8532. return componentsToPath(shapePath);
  8533. };
  8534. /**
  8535. * @private
  8536. */
  8537. DefaultRenderer.prototype.getConnectionPath = function getConnectionPath(connection) {
  8538. var waypoints = connection.waypoints;
  8539. var idx, point, connectionPath = [];
  8540. for (idx = 0; (point = waypoints[idx]); idx++) {
  8541. // take invisible docking into account
  8542. // when creating the path
  8543. point = point.original || point;
  8544. connectionPath.push([ idx === 0 ? 'M' : 'L', point.x, point.y ]);
  8545. }
  8546. return componentsToPath(connectionPath);
  8547. };
  8548. DefaultRenderer.$inject = [ 'eventBus', 'styles' ];
  8549. /**
  8550. * A component that manages shape styles
  8551. */
  8552. function Styles() {
  8553. var defaultTraits = {
  8554. 'no-fill': {
  8555. fill: 'none'
  8556. },
  8557. 'no-border': {
  8558. strokeOpacity: 0.0
  8559. },
  8560. 'no-events': {
  8561. pointerEvents: 'none'
  8562. }
  8563. };
  8564. var self = this;
  8565. /**
  8566. * Builds a style definition from a className, a list of traits and an object
  8567. * of additional attributes.
  8568. *
  8569. * @param {string} className
  8570. * @param {string[]} [traits]
  8571. * @param {Object} [additionalAttrs]
  8572. *
  8573. * @return {Object} the style definition
  8574. */
  8575. this.cls = function(className, traits, additionalAttrs) {
  8576. var attrs = this.style(traits, additionalAttrs);
  8577. return assign$1(attrs, { 'class': className });
  8578. };
  8579. /**
  8580. * Builds a style definition from a list of traits and an object of additional
  8581. * attributes.
  8582. *
  8583. * @param {string[]} [traits]
  8584. * @param {Object} additionalAttrs
  8585. *
  8586. * @return {Object} the style definition
  8587. */
  8588. this.style = function(traits, additionalAttrs) {
  8589. if (!isArray$2(traits) && !additionalAttrs) {
  8590. additionalAttrs = traits;
  8591. traits = [];
  8592. }
  8593. var attrs = reduce(traits, function(attrs, t) {
  8594. return assign$1(attrs, defaultTraits[t] || {});
  8595. }, {});
  8596. return additionalAttrs ? assign$1(attrs, additionalAttrs) : attrs;
  8597. };
  8598. /**
  8599. * Computes a style definition from a list of traits and an object of
  8600. * additional attributes, with custom style definition object.
  8601. *
  8602. * @param {Object} custom
  8603. * @param {string[]} [traits]
  8604. * @param {Object} defaultStyles
  8605. *
  8606. * @return {Object} the style definition
  8607. */
  8608. this.computeStyle = function(custom, traits, defaultStyles) {
  8609. if (!isArray$2(traits)) {
  8610. defaultStyles = traits;
  8611. traits = [];
  8612. }
  8613. return self.style(traits || [], assign$1({}, defaultStyles, custom || {}));
  8614. };
  8615. }
  8616. /**
  8617. * @type { import('didi').ModuleDeclaration }
  8618. */
  8619. var DrawModule = {
  8620. __init__: [ 'defaultRenderer' ],
  8621. defaultRenderer: [ 'type', DefaultRenderer ],
  8622. styles: [ 'type', Styles ]
  8623. };
  8624. /**
  8625. * Failsafe remove an element from a collection
  8626. *
  8627. * @param {Array<Object>} [collection]
  8628. * @param {Object} [element]
  8629. *
  8630. * @return {number} the previous index of the element
  8631. */
  8632. function remove(collection, element) {
  8633. if (!collection || !element) {
  8634. return -1;
  8635. }
  8636. var idx = collection.indexOf(element);
  8637. if (idx !== -1) {
  8638. collection.splice(idx, 1);
  8639. }
  8640. return idx;
  8641. }
  8642. /**
  8643. * Fail save add an element to the given connection, ensuring
  8644. * it does not yet exist.
  8645. *
  8646. * @param {Array<Object>} collection
  8647. * @param {Object} element
  8648. * @param {number} [idx]
  8649. */
  8650. function add(collection, element, idx) {
  8651. if (!collection || !element) {
  8652. return;
  8653. }
  8654. if (typeof idx !== 'number') {
  8655. idx = -1;
  8656. }
  8657. var currentIdx = collection.indexOf(element);
  8658. if (currentIdx !== -1) {
  8659. if (currentIdx === idx) {
  8660. // nothing to do, position has not changed
  8661. return;
  8662. } else {
  8663. if (idx !== -1) {
  8664. // remove from current position
  8665. collection.splice(currentIdx, 1);
  8666. } else {
  8667. // already exists in collection
  8668. return;
  8669. }
  8670. }
  8671. }
  8672. if (idx !== -1) {
  8673. // insert at specified position
  8674. collection.splice(idx, 0, element);
  8675. } else {
  8676. // push to end
  8677. collection.push(element);
  8678. }
  8679. }
  8680. /**
  8681. * @typedef {import('./Types').ConnectionLike} ConnectionLike
  8682. * @typedef {import('./Types').RootLike} RootLike
  8683. * @typedef {import('./Types').ParentLike } ParentLike
  8684. * @typedef {import('./Types').ShapeLike} ShapeLike
  8685. *
  8686. * @typedef { {
  8687. * container?: HTMLElement;
  8688. * deferUpdate?: boolean;
  8689. * width?: number;
  8690. * height?: number;
  8691. * } } CanvasConfig
  8692. * @typedef { {
  8693. * group: SVGElement;
  8694. * index: number;
  8695. * visible: boolean;
  8696. * } } CanvasLayer
  8697. * @typedef { {
  8698. * [key: string]: CanvasLayer;
  8699. * } } CanvasLayers
  8700. * @typedef { {
  8701. * rootElement: ShapeLike;
  8702. * layer: CanvasLayer;
  8703. * } } CanvasPlane
  8704. * @typedef { {
  8705. * scale: number;
  8706. * inner: Rect;
  8707. * outer: Dimensions;
  8708. * } & Rect } CanvasViewbox
  8709. *
  8710. * @typedef {import('./ElementRegistry').default} ElementRegistry
  8711. * @typedef {import('./EventBus').default} EventBus
  8712. * @typedef {import('./GraphicsFactory').default} GraphicsFactory
  8713. *
  8714. * @typedef {import('../util/Types').Dimensions} Dimensions
  8715. * @typedef {import('../util/Types').Point} Point
  8716. * @typedef {import('../util/Types').Rect} Rect
  8717. * @typedef {import('../util/Types').RectTRBL} RectTRBL
  8718. */
  8719. function round(number, resolution) {
  8720. return Math.round(number * resolution) / resolution;
  8721. }
  8722. function ensurePx(number) {
  8723. return isNumber(number) ? number + 'px' : number;
  8724. }
  8725. function findRoot(element) {
  8726. while (element.parent) {
  8727. element = element.parent;
  8728. }
  8729. return element;
  8730. }
  8731. /**
  8732. * Creates a HTML container element for a SVG element with
  8733. * the given configuration
  8734. *
  8735. * @param {CanvasConfig} options
  8736. *
  8737. * @return {HTMLElement} the container element
  8738. */
  8739. function createContainer(options) {
  8740. options = assign$1({}, { width: '100%', height: '100%' }, options);
  8741. const container = options.container || document.body;
  8742. // create a <div> around the svg element with the respective size
  8743. // this way we can always get the correct container size
  8744. // (this is impossible for <svg> elements at the moment)
  8745. const parent = document.createElement('div');
  8746. parent.setAttribute('class', 'djs-container djs-parent');
  8747. assign(parent, {
  8748. position: 'relative',
  8749. overflow: 'hidden',
  8750. width: ensurePx(options.width),
  8751. height: ensurePx(options.height)
  8752. });
  8753. container.appendChild(parent);
  8754. return parent;
  8755. }
  8756. function createGroup(parent, cls, childIndex) {
  8757. const group = create$1('g');
  8758. classes$1(group).add(cls);
  8759. const index = childIndex !== undefined ? childIndex : parent.childNodes.length - 1;
  8760. // must ensure second argument is node or _null_
  8761. // cf. https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore
  8762. parent.insertBefore(group, parent.childNodes[index] || null);
  8763. return group;
  8764. }
  8765. const BASE_LAYER = 'base';
  8766. // render plane contents behind utility layers
  8767. const PLANE_LAYER_INDEX = 0;
  8768. const UTILITY_LAYER_INDEX = 1;
  8769. const REQUIRED_MODEL_ATTRS = {
  8770. shape: [ 'x', 'y', 'width', 'height' ],
  8771. connection: [ 'waypoints' ]
  8772. };
  8773. /**
  8774. * The main drawing canvas.
  8775. *
  8776. * @class
  8777. * @constructor
  8778. *
  8779. * @emits Canvas#canvas.init
  8780. *
  8781. * @param {CanvasConfig|null} config
  8782. * @param {EventBus} eventBus
  8783. * @param {GraphicsFactory} graphicsFactory
  8784. * @param {ElementRegistry} elementRegistry
  8785. */
  8786. function Canvas(config, eventBus, graphicsFactory, elementRegistry) {
  8787. this._eventBus = eventBus;
  8788. this._elementRegistry = elementRegistry;
  8789. this._graphicsFactory = graphicsFactory;
  8790. /**
  8791. * @type {number}
  8792. */
  8793. this._rootsIdx = 0;
  8794. /**
  8795. * @type {CanvasLayers}
  8796. */
  8797. this._layers = {};
  8798. /**
  8799. * @type {CanvasPlane[]}
  8800. */
  8801. this._planes = [];
  8802. /**
  8803. * @type {RootLike|null}
  8804. */
  8805. this._rootElement = null;
  8806. this._init(config || {});
  8807. }
  8808. Canvas.$inject = [
  8809. 'config.canvas',
  8810. 'eventBus',
  8811. 'graphicsFactory',
  8812. 'elementRegistry'
  8813. ];
  8814. /**
  8815. * Creates a <svg> element that is wrapped into a <div>.
  8816. * This way we are always able to correctly figure out the size of the svg element
  8817. * by querying the parent node.
  8818. * (It is not possible to get the size of a svg element cross browser @ 2014-04-01)
  8819. * <div class="djs-container" style="width: {desired-width}, height: {desired-height}">
  8820. * <svg width="100%" height="100%">
  8821. * ...
  8822. * </svg>
  8823. * </div>
  8824. *
  8825. * @param {CanvasConfig} config
  8826. */
  8827. Canvas.prototype._init = function(config) {
  8828. const eventBus = this._eventBus;
  8829. // html container
  8830. const container = this._container = createContainer(config);
  8831. const svg = this._svg = create$1('svg');
  8832. attr$1(svg, { width: '100%', height: '100%' });
  8833. append(container, svg);
  8834. const viewport = this._viewport = createGroup(svg, 'viewport');
  8835. // debounce canvas.viewbox.changed events when deferUpdate is set
  8836. // to help with potential performance issues
  8837. if (config.deferUpdate) {
  8838. this._viewboxChanged = debounce(bind$2(this._viewboxChanged, this), 300);
  8839. }
  8840. eventBus.on('diagram.init', () => {
  8841. /**
  8842. * An event indicating that the canvas is ready to be drawn on.
  8843. *
  8844. * @memberOf Canvas
  8845. *
  8846. * @event canvas.init
  8847. *
  8848. * @type {Object}
  8849. * @property {SVGElement} svg the created svg element
  8850. * @property {SVGElement} viewport the direct parent of diagram elements and shapes
  8851. */
  8852. eventBus.fire('canvas.init', {
  8853. svg: svg,
  8854. viewport: viewport
  8855. });
  8856. });
  8857. // reset viewbox on shape changes to
  8858. // recompute the viewbox
  8859. eventBus.on([
  8860. 'shape.added',
  8861. 'connection.added',
  8862. 'shape.removed',
  8863. 'connection.removed',
  8864. 'elements.changed',
  8865. 'root.set'
  8866. ], () => {
  8867. delete this._cachedViewbox;
  8868. });
  8869. eventBus.on('diagram.destroy', 500, this._destroy, this);
  8870. eventBus.on('diagram.clear', 500, this._clear, this);
  8871. };
  8872. Canvas.prototype._destroy = function() {
  8873. this._eventBus.fire('canvas.destroy', {
  8874. svg: this._svg,
  8875. viewport: this._viewport
  8876. });
  8877. const parent = this._container.parentNode;
  8878. if (parent) {
  8879. parent.removeChild(this._container);
  8880. }
  8881. delete this._svg;
  8882. delete this._container;
  8883. delete this._layers;
  8884. delete this._planes;
  8885. delete this._rootElement;
  8886. delete this._viewport;
  8887. };
  8888. Canvas.prototype._clear = function() {
  8889. const allElements = this._elementRegistry.getAll();
  8890. // remove all elements
  8891. allElements.forEach(element => {
  8892. const type = getType(element);
  8893. if (type === 'root') {
  8894. this.removeRootElement(element);
  8895. } else {
  8896. this._removeElement(element, type);
  8897. }
  8898. });
  8899. // remove all planes
  8900. this._planes = [];
  8901. this._rootElement = null;
  8902. // force recomputation of view box
  8903. delete this._cachedViewbox;
  8904. };
  8905. /**
  8906. * Returns the default layer on which
  8907. * all elements are drawn.
  8908. *
  8909. * @return {SVGElement} The SVG element of the layer.
  8910. */
  8911. Canvas.prototype.getDefaultLayer = function() {
  8912. return this.getLayer(BASE_LAYER, PLANE_LAYER_INDEX);
  8913. };
  8914. /**
  8915. * Returns a layer that is used to draw elements
  8916. * or annotations on it.
  8917. *
  8918. * Non-existing layers retrieved through this method
  8919. * will be created. During creation, the optional index
  8920. * may be used to create layers below or above existing layers.
  8921. * A layer with a certain index is always created above all
  8922. * existing layers with the same index.
  8923. *
  8924. * @param {string} name The name of the layer.
  8925. * @param {number} [index] The index of the layer.
  8926. *
  8927. * @return {SVGElement} The SVG element of the layer.
  8928. */
  8929. Canvas.prototype.getLayer = function(name, index) {
  8930. if (!name) {
  8931. throw new Error('must specify a name');
  8932. }
  8933. let layer = this._layers[name];
  8934. if (!layer) {
  8935. layer = this._layers[name] = this._createLayer(name, index);
  8936. }
  8937. // throw an error if layer creation / retrival is
  8938. // requested on different index
  8939. if (typeof index !== 'undefined' && layer.index !== index) {
  8940. throw new Error('layer <' + name + '> already created at index <' + index + '>');
  8941. }
  8942. return layer.group;
  8943. };
  8944. /**
  8945. * For a given index, return the number of layers that have a higher index and
  8946. * are visible.
  8947. *
  8948. * This is used to determine the node a layer should be inserted at.
  8949. *
  8950. * @param {number} index
  8951. *
  8952. * @return {number}
  8953. */
  8954. Canvas.prototype._getChildIndex = function(index) {
  8955. return reduce(this._layers, function(childIndex, layer) {
  8956. if (layer.visible && index >= layer.index) {
  8957. childIndex++;
  8958. }
  8959. return childIndex;
  8960. }, 0);
  8961. };
  8962. /**
  8963. * Creates a given layer and returns it.
  8964. *
  8965. * @param {string} name
  8966. * @param {number} [index=0]
  8967. *
  8968. * @return {CanvasLayer}
  8969. */
  8970. Canvas.prototype._createLayer = function(name, index) {
  8971. if (typeof index === 'undefined') {
  8972. index = UTILITY_LAYER_INDEX;
  8973. }
  8974. const childIndex = this._getChildIndex(index);
  8975. return {
  8976. group: createGroup(this._viewport, 'layer-' + name, childIndex),
  8977. index: index,
  8978. visible: true
  8979. };
  8980. };
  8981. /**
  8982. * Shows a given layer.
  8983. *
  8984. * @param {string} name The name of the layer.
  8985. *
  8986. * @return {SVGElement} The SVG element of the layer.
  8987. */
  8988. Canvas.prototype.showLayer = function(name) {
  8989. if (!name) {
  8990. throw new Error('must specify a name');
  8991. }
  8992. const layer = this._layers[name];
  8993. if (!layer) {
  8994. throw new Error('layer <' + name + '> does not exist');
  8995. }
  8996. const viewport = this._viewport;
  8997. const group = layer.group;
  8998. const index = layer.index;
  8999. if (layer.visible) {
  9000. return group;
  9001. }
  9002. const childIndex = this._getChildIndex(index);
  9003. viewport.insertBefore(group, viewport.childNodes[childIndex] || null);
  9004. layer.visible = true;
  9005. return group;
  9006. };
  9007. /**
  9008. * Hides a given layer.
  9009. *
  9010. * @param {string} name The name of the layer.
  9011. *
  9012. * @return {SVGElement} The SVG element of the layer.
  9013. */
  9014. Canvas.prototype.hideLayer = function(name) {
  9015. if (!name) {
  9016. throw new Error('must specify a name');
  9017. }
  9018. const layer = this._layers[name];
  9019. if (!layer) {
  9020. throw new Error('layer <' + name + '> does not exist');
  9021. }
  9022. const group = layer.group;
  9023. if (!layer.visible) {
  9024. return group;
  9025. }
  9026. remove$2(group);
  9027. layer.visible = false;
  9028. return group;
  9029. };
  9030. Canvas.prototype._removeLayer = function(name) {
  9031. const layer = this._layers[name];
  9032. if (layer) {
  9033. delete this._layers[name];
  9034. remove$2(layer.group);
  9035. }
  9036. };
  9037. /**
  9038. * Returns the currently active layer. Can be null.
  9039. *
  9040. * @return {CanvasLayer|null} The active layer of `null`.
  9041. */
  9042. Canvas.prototype.getActiveLayer = function() {
  9043. const plane = this._findPlaneForRoot(this.getRootElement());
  9044. if (!plane) {
  9045. return null;
  9046. }
  9047. return plane.layer;
  9048. };
  9049. /**
  9050. * Returns the plane which contains the given element.
  9051. *
  9052. * @param {ShapeLike|ConnectionLike|string} element The element or its ID.
  9053. *
  9054. * @return {RootLike|undefined} The root of the element.
  9055. */
  9056. Canvas.prototype.findRoot = function(element) {
  9057. if (typeof element === 'string') {
  9058. element = this._elementRegistry.get(element);
  9059. }
  9060. if (!element) {
  9061. return;
  9062. }
  9063. const plane = this._findPlaneForRoot(
  9064. findRoot(element)
  9065. ) || {};
  9066. return plane.rootElement;
  9067. };
  9068. /**
  9069. * Return a list of all root elements on the diagram.
  9070. *
  9071. * @return {(RootLike)[]} The list of root elements.
  9072. */
  9073. Canvas.prototype.getRootElements = function() {
  9074. return this._planes.map(function(plane) {
  9075. return plane.rootElement;
  9076. });
  9077. };
  9078. Canvas.prototype._findPlaneForRoot = function(rootElement) {
  9079. return find(this._planes, function(plane) {
  9080. return plane.rootElement === rootElement;
  9081. });
  9082. };
  9083. /**
  9084. * Returns the html element that encloses the
  9085. * drawing canvas.
  9086. *
  9087. * @return {HTMLElement} The HTML element of the container.
  9088. */
  9089. Canvas.prototype.getContainer = function() {
  9090. return this._container;
  9091. };
  9092. // markers //////////////////////
  9093. Canvas.prototype._updateMarker = function(element, marker, add) {
  9094. let container;
  9095. if (!element.id) {
  9096. element = this._elementRegistry.get(element);
  9097. }
  9098. // we need to access all
  9099. container = this._elementRegistry._elements[element.id];
  9100. if (!container) {
  9101. return;
  9102. }
  9103. forEach$1([ container.gfx, container.secondaryGfx ], function(gfx) {
  9104. if (gfx) {
  9105. // invoke either addClass or removeClass based on mode
  9106. if (add) {
  9107. classes$1(gfx).add(marker);
  9108. } else {
  9109. classes$1(gfx).remove(marker);
  9110. }
  9111. }
  9112. });
  9113. /**
  9114. * An event indicating that a marker has been updated for an element
  9115. *
  9116. * @event element.marker.update
  9117. * @type {Object}
  9118. * @property {Element} element the shape
  9119. * @property {SVGElement} gfx the graphical representation of the shape
  9120. * @property {string} marker
  9121. * @property {boolean} add true if the marker was added, false if it got removed
  9122. */
  9123. this._eventBus.fire('element.marker.update', { element: element, gfx: container.gfx, marker: marker, add: !!add });
  9124. };
  9125. /**
  9126. * Adds a marker to an element (basically a css class).
  9127. *
  9128. * Fires the element.marker.update event, making it possible to
  9129. * integrate extension into the marker life-cycle, too.
  9130. *
  9131. * @example
  9132. *
  9133. * ```javascript
  9134. * canvas.addMarker('foo', 'some-marker');
  9135. *
  9136. * const fooGfx = canvas.getGraphics('foo');
  9137. *
  9138. * fooGfx; // <g class="... some-marker"> ... </g>
  9139. * ```
  9140. *
  9141. * @param {ShapeLike|ConnectionLike|string} element The element or its ID.
  9142. * @param {string} marker The marker.
  9143. */
  9144. Canvas.prototype.addMarker = function(element, marker) {
  9145. this._updateMarker(element, marker, true);
  9146. };
  9147. /**
  9148. * Remove a marker from an element.
  9149. *
  9150. * Fires the element.marker.update event, making it possible to
  9151. * integrate extension into the marker life-cycle, too.
  9152. *
  9153. * @param {ShapeLike|ConnectionLike|string} element The element or its ID.
  9154. * @param {string} marker The marker.
  9155. */
  9156. Canvas.prototype.removeMarker = function(element, marker) {
  9157. this._updateMarker(element, marker, false);
  9158. };
  9159. /**
  9160. * Check whether an element has a given marker.
  9161. *
  9162. * @param {ShapeLike|ConnectionLike|string} element The element or its ID.
  9163. * @param {string} marker The marker.
  9164. */
  9165. Canvas.prototype.hasMarker = function(element, marker) {
  9166. if (!element.id) {
  9167. element = this._elementRegistry.get(element);
  9168. }
  9169. const gfx = this.getGraphics(element);
  9170. return classes$1(gfx).has(marker);
  9171. };
  9172. /**
  9173. * Toggles a marker on an element.
  9174. *
  9175. * Fires the element.marker.update event, making it possible to
  9176. * integrate extension into the marker life-cycle, too.
  9177. *
  9178. * @param {ShapeLike|ConnectionLike|string} element The element or its ID.
  9179. * @param {string} marker The marker.
  9180. */
  9181. Canvas.prototype.toggleMarker = function(element, marker) {
  9182. if (this.hasMarker(element, marker)) {
  9183. this.removeMarker(element, marker);
  9184. } else {
  9185. this.addMarker(element, marker);
  9186. }
  9187. };
  9188. /**
  9189. * Returns the current root element.
  9190. *
  9191. * Supports two different modes for handling root elements:
  9192. *
  9193. * 1. if no root element has been added before, an implicit root will be added
  9194. * and returned. This is used in applications that don't require explicit
  9195. * root elements.
  9196. *
  9197. * 2. when root elements have been added before calling `getRootElement`,
  9198. * root elements can be null. This is used for applications that want to manage
  9199. * root elements themselves.
  9200. *
  9201. * @return {RootLike} The current root element.
  9202. */
  9203. Canvas.prototype.getRootElement = function() {
  9204. const rootElement = this._rootElement;
  9205. // can return null if root elements are present but none was set yet
  9206. if (rootElement || this._planes.length) {
  9207. return rootElement;
  9208. }
  9209. return this.setRootElement(this.addRootElement(null));
  9210. };
  9211. /**
  9212. * Adds a given root element and returns it.
  9213. *
  9214. * @param {RootLike} [rootElement] The root element to be added.
  9215. *
  9216. * @return {RootLike} The added root element or an implicit root element.
  9217. */
  9218. Canvas.prototype.addRootElement = function(rootElement) {
  9219. const idx = this._rootsIdx++;
  9220. if (!rootElement) {
  9221. rootElement = {
  9222. id: '__implicitroot_' + idx,
  9223. children: [],
  9224. isImplicit: true
  9225. };
  9226. }
  9227. const layerName = rootElement.layer = 'root-' + idx;
  9228. this._ensureValid('root', rootElement);
  9229. const layer = this.getLayer(layerName, PLANE_LAYER_INDEX);
  9230. this.hideLayer(layerName);
  9231. this._addRoot(rootElement, layer);
  9232. this._planes.push({
  9233. rootElement: rootElement,
  9234. layer: layer
  9235. });
  9236. return rootElement;
  9237. };
  9238. /**
  9239. * Removes a given root element and returns it.
  9240. *
  9241. * @param {RootLike|string} rootElement element or element ID
  9242. *
  9243. * @return {RootLike|undefined} removed element
  9244. */
  9245. Canvas.prototype.removeRootElement = function(rootElement) {
  9246. if (typeof rootElement === 'string') {
  9247. rootElement = this._elementRegistry.get(rootElement);
  9248. }
  9249. const plane = this._findPlaneForRoot(rootElement);
  9250. if (!plane) {
  9251. return;
  9252. }
  9253. // hook up life-cycle events
  9254. this._removeRoot(rootElement);
  9255. // clean up layer
  9256. this._removeLayer(rootElement.layer);
  9257. // clean up plane
  9258. this._planes = this._planes.filter(function(plane) {
  9259. return plane.rootElement !== rootElement;
  9260. });
  9261. // clean up active root
  9262. if (this._rootElement === rootElement) {
  9263. this._rootElement = null;
  9264. }
  9265. return rootElement;
  9266. };
  9267. /**
  9268. * Sets a given element as the new root element for the canvas
  9269. * and returns the new root element.
  9270. *
  9271. * @param {RootLike} rootElement The root element to be set.
  9272. *
  9273. * @return {RootLike} The set root element.
  9274. */
  9275. Canvas.prototype.setRootElement = function(rootElement) {
  9276. if (rootElement === this._rootElement) {
  9277. return;
  9278. }
  9279. let plane;
  9280. if (!rootElement) {
  9281. throw new Error('rootElement required');
  9282. }
  9283. plane = this._findPlaneForRoot(rootElement);
  9284. // give set add semantics for backwards compatibility
  9285. if (!plane) {
  9286. rootElement = this.addRootElement(rootElement);
  9287. }
  9288. this._setRoot(rootElement);
  9289. return rootElement;
  9290. };
  9291. Canvas.prototype._removeRoot = function(element) {
  9292. const elementRegistry = this._elementRegistry,
  9293. eventBus = this._eventBus;
  9294. // simulate element remove event sequence
  9295. eventBus.fire('root.remove', { element: element });
  9296. eventBus.fire('root.removed', { element: element });
  9297. elementRegistry.remove(element);
  9298. };
  9299. Canvas.prototype._addRoot = function(element, gfx) {
  9300. const elementRegistry = this._elementRegistry,
  9301. eventBus = this._eventBus;
  9302. // resemble element add event sequence
  9303. eventBus.fire('root.add', { element: element });
  9304. elementRegistry.add(element, gfx);
  9305. eventBus.fire('root.added', { element: element, gfx: gfx });
  9306. };
  9307. Canvas.prototype._setRoot = function(rootElement, layer) {
  9308. const currentRoot = this._rootElement;
  9309. if (currentRoot) {
  9310. // un-associate previous root element <svg>
  9311. this._elementRegistry.updateGraphics(currentRoot, null, true);
  9312. // hide previous layer
  9313. this.hideLayer(currentRoot.layer);
  9314. }
  9315. if (rootElement) {
  9316. if (!layer) {
  9317. layer = this._findPlaneForRoot(rootElement).layer;
  9318. }
  9319. // associate element with <svg>
  9320. this._elementRegistry.updateGraphics(rootElement, this._svg, true);
  9321. // show root layer
  9322. this.showLayer(rootElement.layer);
  9323. }
  9324. this._rootElement = rootElement;
  9325. this._eventBus.fire('root.set', { element: rootElement });
  9326. };
  9327. Canvas.prototype._ensureValid = function(type, element) {
  9328. if (!element.id) {
  9329. throw new Error('element must have an id');
  9330. }
  9331. if (this._elementRegistry.get(element.id)) {
  9332. throw new Error('element <' + element.id + '> already exists');
  9333. }
  9334. const requiredAttrs = REQUIRED_MODEL_ATTRS[type];
  9335. const valid = every(requiredAttrs, function(attr) {
  9336. return typeof element[attr] !== 'undefined';
  9337. });
  9338. if (!valid) {
  9339. throw new Error(
  9340. 'must supply { ' + requiredAttrs.join(', ') + ' } with ' + type);
  9341. }
  9342. };
  9343. Canvas.prototype._setParent = function(element, parent, parentIndex) {
  9344. add(parent.children, element, parentIndex);
  9345. element.parent = parent;
  9346. };
  9347. /**
  9348. * Adds an element to the canvas.
  9349. *
  9350. * This wires the parent <-> child relationship between the element and
  9351. * a explicitly specified parent or an implicit root element.
  9352. *
  9353. * During add it emits the events
  9354. *
  9355. * * <{type}.add> (element, parent)
  9356. * * <{type}.added> (element, gfx)
  9357. *
  9358. * Extensions may hook into these events to perform their magic.
  9359. *
  9360. * @param {string} type
  9361. * @param {ConnectionLike|ShapeLike} element
  9362. * @param {ShapeLike} [parent]
  9363. * @param {number} [parentIndex]
  9364. *
  9365. * @return {ConnectionLike|ShapeLike} The added element.
  9366. */
  9367. Canvas.prototype._addElement = function(type, element, parent, parentIndex) {
  9368. parent = parent || this.getRootElement();
  9369. const eventBus = this._eventBus,
  9370. graphicsFactory = this._graphicsFactory;
  9371. this._ensureValid(type, element);
  9372. eventBus.fire(type + '.add', { element: element, parent: parent });
  9373. this._setParent(element, parent, parentIndex);
  9374. // create graphics
  9375. const gfx = graphicsFactory.create(type, element, parentIndex);
  9376. this._elementRegistry.add(element, gfx);
  9377. // update its visual
  9378. graphicsFactory.update(type, element, gfx);
  9379. eventBus.fire(type + '.added', { element: element, gfx: gfx });
  9380. return element;
  9381. };
  9382. /**
  9383. * Adds a shape to the canvas.
  9384. *
  9385. * @param {ShapeLike} shape The shape to be added
  9386. * @param {ParentLike} [parent] The shape's parent.
  9387. * @param {number} [parentIndex] The index at which to add the shape to the parent's children.
  9388. *
  9389. * @return {ShapeLike} The added shape.
  9390. */
  9391. Canvas.prototype.addShape = function(shape, parent, parentIndex) {
  9392. return this._addElement('shape', shape, parent, parentIndex);
  9393. };
  9394. /**
  9395. * Adds a connection to the canvas.
  9396. *
  9397. * @param {ConnectionLike} connection The connection to be added.
  9398. * @param {ParentLike} [parent] The connection's parent.
  9399. * @param {number} [parentIndex] The index at which to add the connection to the parent's children.
  9400. *
  9401. * @return {ConnectionLike} The added connection.
  9402. */
  9403. Canvas.prototype.addConnection = function(connection, parent, parentIndex) {
  9404. return this._addElement('connection', connection, parent, parentIndex);
  9405. };
  9406. /**
  9407. * Internal remove element
  9408. */
  9409. Canvas.prototype._removeElement = function(element, type) {
  9410. const elementRegistry = this._elementRegistry,
  9411. graphicsFactory = this._graphicsFactory,
  9412. eventBus = this._eventBus;
  9413. element = elementRegistry.get(element.id || element);
  9414. if (!element) {
  9415. // element was removed already
  9416. return;
  9417. }
  9418. eventBus.fire(type + '.remove', { element: element });
  9419. graphicsFactory.remove(element);
  9420. // unset parent <-> child relationship
  9421. remove(element.parent && element.parent.children, element);
  9422. element.parent = null;
  9423. eventBus.fire(type + '.removed', { element: element });
  9424. elementRegistry.remove(element);
  9425. return element;
  9426. };
  9427. /**
  9428. * Removes a shape from the canvas.
  9429. *
  9430. * @fires ShapeRemoveEvent
  9431. * @fires ShapeRemovedEvent
  9432. *
  9433. * @param {ShapeLike|string} shape The shape or its ID.
  9434. *
  9435. * @return {ShapeLike} The removed shape.
  9436. */
  9437. Canvas.prototype.removeShape = function(shape) {
  9438. /**
  9439. * An event indicating that a shape is about to be removed from the canvas.
  9440. *
  9441. * @memberOf Canvas
  9442. *
  9443. * @event ShapeRemoveEvent
  9444. * @type {Object}
  9445. * @property {ShapeLike} element The shape.
  9446. * @property {SVGElement} gfx The graphical element.
  9447. */
  9448. /**
  9449. * An event indicating that a shape has been removed from the canvas.
  9450. *
  9451. * @memberOf Canvas
  9452. *
  9453. * @event ShapeRemovedEvent
  9454. * @type {Object}
  9455. * @property {ShapeLike} element The shape.
  9456. * @property {SVGElement} gfx The graphical element.
  9457. */
  9458. return this._removeElement(shape, 'shape');
  9459. };
  9460. /**
  9461. * Removes a connection from the canvas.
  9462. *
  9463. * @fires ConnectionRemoveEvent
  9464. * @fires ConnectionRemovedEvent
  9465. *
  9466. * @param {ConnectionLike|string} connection The connection or its ID.
  9467. *
  9468. * @return {ConnectionLike} The removed connection.
  9469. */
  9470. Canvas.prototype.removeConnection = function(connection) {
  9471. /**
  9472. * An event indicating that a connection is about to be removed from the canvas.
  9473. *
  9474. * @memberOf Canvas
  9475. *
  9476. * @event ConnectionRemoveEvent
  9477. * @type {Object}
  9478. * @property {ConnectionLike} element The connection.
  9479. * @property {SVGElement} gfx The graphical element.
  9480. */
  9481. /**
  9482. * An event indicating that a connection has been removed from the canvas.
  9483. *
  9484. * @memberOf Canvas
  9485. *
  9486. * @event ConnectionRemovedEvent
  9487. * @type {Object}
  9488. * @property {ConnectionLike} element The connection.
  9489. * @property {SVGElement} gfx The graphical element.
  9490. */
  9491. return this._removeElement(connection, 'connection');
  9492. };
  9493. /**
  9494. * Returns the graphical element of an element.
  9495. *
  9496. * @param {ShapeLike|ConnectionLike|string} element The element or its ID.
  9497. * @param {boolean} [secondary=false] Whether to return the secondary graphical element.
  9498. *
  9499. * @return {SVGElement} The graphical element.
  9500. */
  9501. Canvas.prototype.getGraphics = function(element, secondary) {
  9502. return this._elementRegistry.getGraphics(element, secondary);
  9503. };
  9504. /**
  9505. * Perform a viewbox update via a given change function.
  9506. *
  9507. * @param {Function} changeFn
  9508. */
  9509. Canvas.prototype._changeViewbox = function(changeFn) {
  9510. // notify others of the upcoming viewbox change
  9511. this._eventBus.fire('canvas.viewbox.changing');
  9512. // perform actual change
  9513. changeFn.apply(this);
  9514. // reset the cached viewbox so that
  9515. // a new get operation on viewbox or zoom
  9516. // triggers a viewbox re-computation
  9517. this._cachedViewbox = null;
  9518. // notify others of the change; this step
  9519. // may or may not be debounced
  9520. this._viewboxChanged();
  9521. };
  9522. Canvas.prototype._viewboxChanged = function() {
  9523. this._eventBus.fire('canvas.viewbox.changed', { viewbox: this.viewbox() });
  9524. };
  9525. /**
  9526. * Gets or sets the view box of the canvas, i.e. the
  9527. * area that is currently displayed.
  9528. *
  9529. * The getter may return a cached viewbox (if it is currently
  9530. * changing). To force a recomputation, pass `false` as the first argument.
  9531. *
  9532. * @example
  9533. *
  9534. * ```javascript
  9535. * canvas.viewbox({ x: 100, y: 100, width: 500, height: 500 })
  9536. *
  9537. * // sets the visible area of the diagram to (100|100) -> (600|100)
  9538. * // and and scales it according to the diagram width
  9539. *
  9540. * const viewbox = canvas.viewbox(); // pass `false` to force recomputing the box.
  9541. *
  9542. * console.log(viewbox);
  9543. * // {
  9544. * // inner: Dimensions,
  9545. * // outer: Dimensions,
  9546. * // scale,
  9547. * // x, y,
  9548. * // width, height
  9549. * // }
  9550. *
  9551. * // if the current diagram is zoomed and scrolled, you may reset it to the
  9552. * // default zoom via this method, too:
  9553. *
  9554. * const zoomedAndScrolledViewbox = canvas.viewbox();
  9555. *
  9556. * canvas.viewbox({
  9557. * x: 0,
  9558. * y: 0,
  9559. * width: zoomedAndScrolledViewbox.outer.width,
  9560. * height: zoomedAndScrolledViewbox.outer.height
  9561. * });
  9562. * ```
  9563. *
  9564. * @param {Rect} [box] The viewbox to be set.
  9565. *
  9566. * @return {CanvasViewbox} The set viewbox.
  9567. */
  9568. Canvas.prototype.viewbox = function(box) {
  9569. if (box === undefined && this._cachedViewbox) {
  9570. return this._cachedViewbox;
  9571. }
  9572. const viewport = this._viewport,
  9573. outerBox = this.getSize();
  9574. let innerBox,
  9575. matrix,
  9576. activeLayer,
  9577. transform,
  9578. scale,
  9579. x, y;
  9580. if (!box) {
  9581. // compute the inner box based on the
  9582. // diagrams active layer. This allows us to exclude
  9583. // external components, such as overlays
  9584. activeLayer = this._rootElement ? this.getActiveLayer() : null;
  9585. innerBox = activeLayer && activeLayer.getBBox() || {};
  9586. transform = transform$1(viewport);
  9587. matrix = transform ? transform.matrix : createMatrix();
  9588. scale = round(matrix.a, 1000);
  9589. x = round(-matrix.e || 0, 1000);
  9590. y = round(-matrix.f || 0, 1000);
  9591. box = this._cachedViewbox = {
  9592. x: x ? x / scale : 0,
  9593. y: y ? y / scale : 0,
  9594. width: outerBox.width / scale,
  9595. height: outerBox.height / scale,
  9596. scale: scale,
  9597. inner: {
  9598. width: innerBox.width || 0,
  9599. height: innerBox.height || 0,
  9600. x: innerBox.x || 0,
  9601. y: innerBox.y || 0
  9602. },
  9603. outer: outerBox
  9604. };
  9605. return box;
  9606. } else {
  9607. this._changeViewbox(function() {
  9608. scale = Math.min(outerBox.width / box.width, outerBox.height / box.height);
  9609. const matrix = this._svg.createSVGMatrix()
  9610. .scale(scale)
  9611. .translate(-box.x, -box.y);
  9612. transform$1(viewport, matrix);
  9613. });
  9614. }
  9615. return box;
  9616. };
  9617. /**
  9618. * Gets or sets the scroll of the canvas.
  9619. *
  9620. * @param {Point} [delta] The scroll to be set.
  9621. *
  9622. * @return {Point}
  9623. */
  9624. Canvas.prototype.scroll = function(delta) {
  9625. const node = this._viewport;
  9626. let matrix = node.getCTM();
  9627. if (delta) {
  9628. this._changeViewbox(function() {
  9629. delta = assign$1({ dx: 0, dy: 0 }, delta || {});
  9630. matrix = this._svg.createSVGMatrix().translate(delta.dx, delta.dy).multiply(matrix);
  9631. setCTM(node, matrix);
  9632. });
  9633. }
  9634. return { x: matrix.e, y: matrix.f };
  9635. };
  9636. /**
  9637. * Scrolls the viewbox to contain the given element.
  9638. * Optionally specify a padding to be applied to the edges.
  9639. *
  9640. * @param {ShapeLike|ConnectionLike|string} element The element to scroll to or its ID.
  9641. * @param {RectTRBL|number} [padding=100] The padding to be applied. Can also specify top, bottom, left and right.
  9642. */
  9643. Canvas.prototype.scrollToElement = function(element, padding) {
  9644. let defaultPadding = 100;
  9645. if (typeof element === 'string') {
  9646. element = this._elementRegistry.get(element);
  9647. }
  9648. // set to correct rootElement
  9649. const rootElement = this.findRoot(element);
  9650. if (rootElement !== this.getRootElement()) {
  9651. this.setRootElement(rootElement);
  9652. }
  9653. // element is rootElement, do not change viewport
  9654. if (rootElement === element) {
  9655. return;
  9656. }
  9657. if (!padding) {
  9658. padding = {};
  9659. }
  9660. if (typeof padding === 'number') {
  9661. defaultPadding = padding;
  9662. }
  9663. padding = {
  9664. top: padding.top || defaultPadding,
  9665. right: padding.right || defaultPadding,
  9666. bottom: padding.bottom || defaultPadding,
  9667. left: padding.left || defaultPadding
  9668. };
  9669. const elementBounds = getBBox(element),
  9670. elementTrbl = asTRBL(elementBounds),
  9671. viewboxBounds = this.viewbox(),
  9672. zoom = this.zoom();
  9673. let dx, dy;
  9674. // shrink viewboxBounds with padding
  9675. viewboxBounds.y += padding.top / zoom;
  9676. viewboxBounds.x += padding.left / zoom;
  9677. viewboxBounds.width -= (padding.right + padding.left) / zoom;
  9678. viewboxBounds.height -= (padding.bottom + padding.top) / zoom;
  9679. const viewboxTrbl = asTRBL(viewboxBounds);
  9680. const canFit = elementBounds.width < viewboxBounds.width && elementBounds.height < viewboxBounds.height;
  9681. if (!canFit) {
  9682. // top-left when element can't fit
  9683. dx = elementBounds.x - viewboxBounds.x;
  9684. dy = elementBounds.y - viewboxBounds.y;
  9685. } else {
  9686. const dRight = Math.max(0, elementTrbl.right - viewboxTrbl.right),
  9687. dLeft = Math.min(0, elementTrbl.left - viewboxTrbl.left),
  9688. dBottom = Math.max(0, elementTrbl.bottom - viewboxTrbl.bottom),
  9689. dTop = Math.min(0, elementTrbl.top - viewboxTrbl.top);
  9690. dx = dRight || dLeft;
  9691. dy = dBottom || dTop;
  9692. }
  9693. this.scroll({ dx: -dx * zoom, dy: -dy * zoom });
  9694. };
  9695. /**
  9696. * Gets or sets the current zoom of the canvas, optionally zooming to the
  9697. * specified position.
  9698. *
  9699. * The getter may return a cached zoom level. Call it with `false` as the first
  9700. * argument to force recomputation of the current level.
  9701. *
  9702. * @param {number|'fit-viewport'} [newScale] The new zoom level, either a number,
  9703. * i.e. 0.9, or `fit-viewport` to adjust the size to fit the current viewport.
  9704. * @param {Point} [center] The reference point { x: ..., y: ...} to zoom to.
  9705. *
  9706. * @return {number} The set zoom level.
  9707. */
  9708. Canvas.prototype.zoom = function(newScale, center) {
  9709. if (!newScale) {
  9710. return this.viewbox(newScale).scale;
  9711. }
  9712. if (newScale === 'fit-viewport') {
  9713. return this._fitViewport(center);
  9714. }
  9715. let outer,
  9716. matrix;
  9717. this._changeViewbox(function() {
  9718. if (typeof center !== 'object') {
  9719. outer = this.viewbox().outer;
  9720. center = {
  9721. x: outer.width / 2,
  9722. y: outer.height / 2
  9723. };
  9724. }
  9725. matrix = this._setZoom(newScale, center);
  9726. });
  9727. return round(matrix.a, 1000);
  9728. };
  9729. function setCTM(node, m) {
  9730. const mstr = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.e + ',' + m.f + ')';
  9731. node.setAttribute('transform', mstr);
  9732. }
  9733. Canvas.prototype._fitViewport = function(center) {
  9734. const vbox = this.viewbox(),
  9735. outer = vbox.outer,
  9736. inner = vbox.inner;
  9737. let newScale,
  9738. newViewbox;
  9739. // display the complete diagram without zooming in.
  9740. // instead of relying on internal zoom, we perform a
  9741. // hard reset on the canvas viewbox to realize this
  9742. //
  9743. // if diagram does not need to be zoomed in, we focus it around
  9744. // the diagram origin instead
  9745. if (inner.x >= 0 &&
  9746. inner.y >= 0 &&
  9747. inner.x + inner.width <= outer.width &&
  9748. inner.y + inner.height <= outer.height &&
  9749. !center) {
  9750. newViewbox = {
  9751. x: 0,
  9752. y: 0,
  9753. width: Math.max(inner.width + inner.x, outer.width),
  9754. height: Math.max(inner.height + inner.y, outer.height)
  9755. };
  9756. } else {
  9757. newScale = Math.min(1, outer.width / inner.width, outer.height / inner.height);
  9758. newViewbox = {
  9759. x: inner.x + (center ? inner.width / 2 - outer.width / newScale / 2 : 0),
  9760. y: inner.y + (center ? inner.height / 2 - outer.height / newScale / 2 : 0),
  9761. width: outer.width / newScale,
  9762. height: outer.height / newScale
  9763. };
  9764. }
  9765. this.viewbox(newViewbox);
  9766. return this.viewbox(false).scale;
  9767. };
  9768. Canvas.prototype._setZoom = function(scale, center) {
  9769. const svg = this._svg,
  9770. viewport = this._viewport;
  9771. const matrix = svg.createSVGMatrix();
  9772. const point = svg.createSVGPoint();
  9773. let centerPoint,
  9774. originalPoint,
  9775. currentMatrix,
  9776. scaleMatrix,
  9777. newMatrix;
  9778. currentMatrix = viewport.getCTM();
  9779. const currentScale = currentMatrix.a;
  9780. if (center) {
  9781. centerPoint = assign$1(point, center);
  9782. // revert applied viewport transformations
  9783. originalPoint = centerPoint.matrixTransform(currentMatrix.inverse());
  9784. // create scale matrix
  9785. scaleMatrix = matrix
  9786. .translate(originalPoint.x, originalPoint.y)
  9787. .scale(1 / currentScale * scale)
  9788. .translate(-originalPoint.x, -originalPoint.y);
  9789. newMatrix = currentMatrix.multiply(scaleMatrix);
  9790. } else {
  9791. newMatrix = matrix.scale(scale);
  9792. }
  9793. setCTM(this._viewport, newMatrix);
  9794. return newMatrix;
  9795. };
  9796. /**
  9797. * Returns the size of the canvas.
  9798. *
  9799. * @return {Dimensions} The size of the canvas.
  9800. */
  9801. Canvas.prototype.getSize = function() {
  9802. return {
  9803. width: this._container.clientWidth,
  9804. height: this._container.clientHeight
  9805. };
  9806. };
  9807. /**
  9808. * Returns the absolute bounding box of an element.
  9809. *
  9810. * The absolute bounding box may be used to display overlays in the callers
  9811. * (browser) coordinate system rather than the zoomed in/out canvas coordinates.
  9812. *
  9813. * @param {ShapeLike|ConnectionLike} element The element.
  9814. *
  9815. * @return {Rect} The element's absolute bounding box.
  9816. */
  9817. Canvas.prototype.getAbsoluteBBox = function(element) {
  9818. const vbox = this.viewbox();
  9819. let bbox;
  9820. // connection
  9821. // use svg bbox
  9822. if (element.waypoints) {
  9823. const gfx = this.getGraphics(element);
  9824. bbox = gfx.getBBox();
  9825. }
  9826. // shapes
  9827. // use data
  9828. else {
  9829. bbox = element;
  9830. }
  9831. const x = bbox.x * vbox.scale - vbox.x * vbox.scale;
  9832. const y = bbox.y * vbox.scale - vbox.y * vbox.scale;
  9833. const width = bbox.width * vbox.scale;
  9834. const height = bbox.height * vbox.scale;
  9835. return {
  9836. x: x,
  9837. y: y,
  9838. width: width,
  9839. height: height
  9840. };
  9841. };
  9842. /**
  9843. * Fires an event so other modules can react to the canvas resizing.
  9844. */
  9845. Canvas.prototype.resized = function() {
  9846. // force recomputation of view box
  9847. delete this._cachedViewbox;
  9848. this._eventBus.fire('canvas.resized');
  9849. };
  9850. var ELEMENT_ID = 'data-element-id';
  9851. /**
  9852. * @typedef {import('./Types').ElementLike} ElementLike
  9853. *
  9854. * @typedef {import('./EventBus').default} EventBus
  9855. *
  9856. * @typedef { (element: ElementLike, gfx: SVGElement) => boolean|any } ElementRegistryFilterCallback
  9857. * @typedef { (element: ElementLike, gfx: SVGElement) => any } ElementRegistryForEachCallback
  9858. */
  9859. /**
  9860. * A registry that keeps track of all shapes in the diagram.
  9861. *
  9862. * @class
  9863. * @constructor
  9864. *
  9865. * @param {EventBus} eventBus
  9866. */
  9867. function ElementRegistry(eventBus) {
  9868. /**
  9869. * @type { {
  9870. * [id: string]: {
  9871. * element: ElementLike;
  9872. * gfx?: SVGElement;
  9873. * secondaryGfx?: SVGElement;
  9874. * }
  9875. * } }
  9876. */
  9877. this._elements = {};
  9878. this._eventBus = eventBus;
  9879. }
  9880. ElementRegistry.$inject = [ 'eventBus' ];
  9881. /**
  9882. * Add an element and its graphical representation(s) to the registry.
  9883. *
  9884. * @param {ElementLike} element The element to be added.
  9885. * @param {SVGElement} gfx The primary graphical representation.
  9886. * @param {SVGElement} [secondaryGfx] The secondary graphical representation.
  9887. */
  9888. ElementRegistry.prototype.add = function(element, gfx, secondaryGfx) {
  9889. var id = element.id;
  9890. this._validateId(id);
  9891. // associate dom node with element
  9892. attr$1(gfx, ELEMENT_ID, id);
  9893. if (secondaryGfx) {
  9894. attr$1(secondaryGfx, ELEMENT_ID, id);
  9895. }
  9896. this._elements[id] = { element: element, gfx: gfx, secondaryGfx: secondaryGfx };
  9897. };
  9898. /**
  9899. * Remove an element from the registry.
  9900. *
  9901. * @param {ElementLike|string} element
  9902. */
  9903. ElementRegistry.prototype.remove = function(element) {
  9904. var elements = this._elements,
  9905. id = element.id || element,
  9906. container = id && elements[id];
  9907. if (container) {
  9908. // unset element id on gfx
  9909. attr$1(container.gfx, ELEMENT_ID, '');
  9910. if (container.secondaryGfx) {
  9911. attr$1(container.secondaryGfx, ELEMENT_ID, '');
  9912. }
  9913. delete elements[id];
  9914. }
  9915. };
  9916. /**
  9917. * Update an elements ID.
  9918. *
  9919. * @param {ElementLike|string} element The element or its ID.
  9920. * @param {string} newId The new ID.
  9921. */
  9922. ElementRegistry.prototype.updateId = function(element, newId) {
  9923. this._validateId(newId);
  9924. if (typeof element === 'string') {
  9925. element = this.get(element);
  9926. }
  9927. this._eventBus.fire('element.updateId', {
  9928. element: element,
  9929. newId: newId
  9930. });
  9931. var gfx = this.getGraphics(element),
  9932. secondaryGfx = this.getGraphics(element, true);
  9933. this.remove(element);
  9934. element.id = newId;
  9935. this.add(element, gfx, secondaryGfx);
  9936. };
  9937. /**
  9938. * Update the graphical representation of an element.
  9939. *
  9940. * @param {ElementLike|string} filter The element or its ID.
  9941. * @param {SVGElement} gfx The new graphical representation.
  9942. * @param {boolean} [secondary=false] Whether to update the secondary graphical representation.
  9943. */
  9944. ElementRegistry.prototype.updateGraphics = function(filter, gfx, secondary) {
  9945. var id = filter.id || filter;
  9946. var container = this._elements[id];
  9947. if (secondary) {
  9948. container.secondaryGfx = gfx;
  9949. } else {
  9950. container.gfx = gfx;
  9951. }
  9952. if (gfx) {
  9953. attr$1(gfx, ELEMENT_ID, id);
  9954. }
  9955. return gfx;
  9956. };
  9957. /**
  9958. * Get the element with the given ID or graphical representation.
  9959. *
  9960. * @example
  9961. *
  9962. * ```javascript
  9963. * elementRegistry.get('SomeElementId_1');
  9964. *
  9965. * elementRegistry.get(gfx);
  9966. * ```
  9967. *
  9968. * @param {string|SVGElement} filter The elements ID or graphical representation.
  9969. *
  9970. * @return {ElementLike|undefined} The element.
  9971. */
  9972. ElementRegistry.prototype.get = function(filter) {
  9973. var id;
  9974. if (typeof filter === 'string') {
  9975. id = filter;
  9976. } else {
  9977. id = filter && attr$1(filter, ELEMENT_ID);
  9978. }
  9979. var container = this._elements[id];
  9980. return container && container.element;
  9981. };
  9982. /**
  9983. * Return all elements that match a given filter function.
  9984. *
  9985. * @param {ElementRegistryFilterCallback} fn The filter function.
  9986. *
  9987. * @return {ElementLike[]} The matching elements.
  9988. */
  9989. ElementRegistry.prototype.filter = function(fn) {
  9990. var filtered = [];
  9991. this.forEach(function(element, gfx) {
  9992. if (fn(element, gfx)) {
  9993. filtered.push(element);
  9994. }
  9995. });
  9996. return filtered;
  9997. };
  9998. /**
  9999. * Return the first element that matches the given filter function.
  10000. *
  10001. * @param {ElementRegistryFilterCallback} fn The filter function.
  10002. *
  10003. * @return {ElementLike|undefined} The matching element.
  10004. */
  10005. ElementRegistry.prototype.find = function(fn) {
  10006. var map = this._elements,
  10007. keys = Object.keys(map);
  10008. for (var i = 0; i < keys.length; i++) {
  10009. var id = keys[i],
  10010. container = map[id],
  10011. element = container.element,
  10012. gfx = container.gfx;
  10013. if (fn(element, gfx)) {
  10014. return element;
  10015. }
  10016. }
  10017. };
  10018. /**
  10019. * Get all elements.
  10020. *
  10021. * @return {ElementLike[]} All elements.
  10022. */
  10023. ElementRegistry.prototype.getAll = function() {
  10024. return this.filter(function(e) { return e; });
  10025. };
  10026. /**
  10027. * Execute a given function for each element.
  10028. *
  10029. * @param {ElementRegistryForEachCallback} fn The function to execute.
  10030. */
  10031. ElementRegistry.prototype.forEach = function(fn) {
  10032. var map = this._elements;
  10033. Object.keys(map).forEach(function(id) {
  10034. var container = map[id],
  10035. element = container.element,
  10036. gfx = container.gfx;
  10037. return fn(element, gfx);
  10038. });
  10039. };
  10040. /**
  10041. * Return the graphical representation of an element.
  10042. *
  10043. * @example
  10044. *
  10045. * ```javascript
  10046. * elementRegistry.getGraphics('SomeElementId_1');
  10047. *
  10048. * elementRegistry.getGraphics(rootElement); // <g ...>
  10049. *
  10050. * elementRegistry.getGraphics(rootElement, true); // <svg ...>
  10051. * ```
  10052. *
  10053. * @param {ElementLike|string} filter The element or its ID.
  10054. * @param {boolean} [secondary=false] Whether to return the secondary graphical representation.
  10055. *
  10056. * @return {SVGElement} The graphical representation.
  10057. */
  10058. ElementRegistry.prototype.getGraphics = function(filter, secondary) {
  10059. var id = filter.id || filter;
  10060. var container = this._elements[id];
  10061. return container && (secondary ? container.secondaryGfx : container.gfx);
  10062. };
  10063. /**
  10064. * Validate an ID and throw an error if invalid.
  10065. *
  10066. * @param {string} id
  10067. *
  10068. * @throws {Error} Error indicating that the ID is invalid or already assigned.
  10069. */
  10070. ElementRegistry.prototype._validateId = function(id) {
  10071. if (!id) {
  10072. throw new Error('element must have an id');
  10073. }
  10074. if (this._elements[id]) {
  10075. throw new Error('element with id ' + id + ' already added');
  10076. }
  10077. };
  10078. /**
  10079. * Extends a collection with {@link Refs} aware methods
  10080. *
  10081. * @param {Array<Object>} collection
  10082. * @param {Refs} refs instance
  10083. * @param {Object} property represented by the collection
  10084. * @param {Object} target object the collection is attached to
  10085. *
  10086. * @return {RefsCollection<Object>} the extended array
  10087. */
  10088. function extend(collection, refs, property, target) {
  10089. var inverseProperty = property.inverse;
  10090. /**
  10091. * Removes the given element from the array and returns it.
  10092. *
  10093. * @method RefsCollection#remove
  10094. *
  10095. * @param {Object} element the element to remove
  10096. */
  10097. Object.defineProperty(collection, 'remove', {
  10098. value: function (element) {
  10099. var idx = this.indexOf(element);
  10100. if (idx !== -1) {
  10101. this.splice(idx, 1);
  10102. // unset inverse
  10103. refs.unset(element, inverseProperty, target);
  10104. }
  10105. return element;
  10106. }
  10107. });
  10108. /**
  10109. * Returns true if the collection contains the given element
  10110. *
  10111. * @method RefsCollection#contains
  10112. *
  10113. * @param {Object} element the element to check for
  10114. */
  10115. Object.defineProperty(collection, 'contains', {
  10116. value: function (element) {
  10117. return this.indexOf(element) !== -1;
  10118. }
  10119. });
  10120. /**
  10121. * Adds an element to the array, unless it exists already (set semantics).
  10122. *
  10123. * @method RefsCollection#add
  10124. *
  10125. * @param {Object} element the element to add
  10126. * @param {Number} optional index to add element to
  10127. * (possibly moving other elements around)
  10128. */
  10129. Object.defineProperty(collection, 'add', {
  10130. value: function (element, idx) {
  10131. var currentIdx = this.indexOf(element);
  10132. if (typeof idx === 'undefined') {
  10133. if (currentIdx !== -1) {
  10134. // element already in collection (!)
  10135. return;
  10136. }
  10137. // add to end of array, as no idx is specified
  10138. idx = this.length;
  10139. }
  10140. // handle already in collection
  10141. if (currentIdx !== -1) {
  10142. // remove element from currentIdx
  10143. this.splice(currentIdx, 1);
  10144. }
  10145. // add element at idx
  10146. this.splice(idx, 0, element);
  10147. if (currentIdx === -1) {
  10148. // set inverse, unless element was
  10149. // in collection already
  10150. refs.set(element, inverseProperty, target);
  10151. }
  10152. }
  10153. });
  10154. // a simple marker, identifying this element
  10155. // as being a refs collection
  10156. Object.defineProperty(collection, '__refs_collection', {
  10157. value: true
  10158. });
  10159. return collection;
  10160. }
  10161. /**
  10162. * Checks if a given collection is extended
  10163. *
  10164. * @param {Array<Object>} collection
  10165. *
  10166. * @return {boolean}
  10167. */
  10168. function isExtended(collection) {
  10169. return collection.__refs_collection === true;
  10170. }
  10171. function hasOwnProperty$1(e, property) {
  10172. return Object.prototype.hasOwnProperty.call(e, property.name || property);
  10173. }
  10174. function defineCollectionProperty(ref, property, target) {
  10175. var collection = extend(target[property.name] || [], ref, property, target);
  10176. Object.defineProperty(target, property.name, {
  10177. enumerable: property.enumerable,
  10178. value: collection
  10179. });
  10180. if (collection.length) {
  10181. collection.forEach(function (o) {
  10182. ref.set(o, property.inverse, target);
  10183. });
  10184. }
  10185. }
  10186. function defineProperty$1(ref, property, target) {
  10187. var inverseProperty = property.inverse;
  10188. var _value = target[property.name];
  10189. Object.defineProperty(target, property.name, {
  10190. configurable: property.configurable,
  10191. enumerable: property.enumerable,
  10192. get: function () {
  10193. return _value;
  10194. },
  10195. set: function (value) {
  10196. // return if we already performed all changes
  10197. if (value === _value) {
  10198. return;
  10199. }
  10200. var old = _value;
  10201. // temporary set null
  10202. _value = null;
  10203. if (old) {
  10204. ref.unset(old, inverseProperty, target);
  10205. }
  10206. // set new value
  10207. _value = value;
  10208. // set inverse value
  10209. ref.set(_value, inverseProperty, target);
  10210. }
  10211. });
  10212. }
  10213. /**
  10214. * Creates a new references object defining two inversly related
  10215. * attribute descriptors a and b.
  10216. *
  10217. * <p>
  10218. * When bound to an object using {@link Refs#bind} the references
  10219. * get activated and ensure that add and remove operations are applied
  10220. * reversely, too.
  10221. * </p>
  10222. *
  10223. * <p>
  10224. * For attributes represented as collections {@link Refs} provides the
  10225. * {@link RefsCollection#add}, {@link RefsCollection#remove} and {@link RefsCollection#contains} extensions
  10226. * that must be used to properly hook into the inverse change mechanism.
  10227. * </p>
  10228. *
  10229. * @class Refs
  10230. *
  10231. * @classdesc A bi-directional reference between two attributes.
  10232. *
  10233. * @param {Refs.AttributeDescriptor} a property descriptor
  10234. * @param {Refs.AttributeDescriptor} b property descriptor
  10235. *
  10236. * @example
  10237. *
  10238. * var refs = Refs({ name: 'wheels', collection: true, enumerable: true }, { name: 'car' });
  10239. *
  10240. * var car = { name: 'toyota' };
  10241. * var wheels = [{ pos: 'front-left' }, { pos: 'front-right' }];
  10242. *
  10243. * refs.bind(car, 'wheels');
  10244. *
  10245. * car.wheels // []
  10246. * car.wheels.add(wheels[0]);
  10247. * car.wheels.add(wheels[1]);
  10248. *
  10249. * car.wheels // [{ pos: 'front-left' }, { pos: 'front-right' }]
  10250. *
  10251. * wheels[0].car // { name: 'toyota' };
  10252. * car.wheels.remove(wheels[0]);
  10253. *
  10254. * wheels[0].car // undefined
  10255. */
  10256. function Refs(a, b) {
  10257. if (!(this instanceof Refs)) {
  10258. return new Refs(a, b);
  10259. }
  10260. // link
  10261. a.inverse = b;
  10262. b.inverse = a;
  10263. this.props = {};
  10264. this.props[a.name] = a;
  10265. this.props[b.name] = b;
  10266. }
  10267. /**
  10268. * Binds one side of a bi-directional reference to a
  10269. * target object.
  10270. *
  10271. * @memberOf Refs
  10272. *
  10273. * @param {Object} target
  10274. * @param {String} property
  10275. */
  10276. Refs.prototype.bind = function (target, property) {
  10277. if (typeof property === 'string') {
  10278. if (!this.props[property]) {
  10279. throw new Error('no property <' + property + '> in ref');
  10280. }
  10281. property = this.props[property];
  10282. }
  10283. if (property.collection) {
  10284. defineCollectionProperty(this, property, target);
  10285. } else {
  10286. defineProperty$1(this, property, target);
  10287. }
  10288. };
  10289. Refs.prototype.ensureRefsCollection = function (target, property) {
  10290. var collection = target[property.name];
  10291. if (!isExtended(collection)) {
  10292. defineCollectionProperty(this, property, target);
  10293. }
  10294. return collection;
  10295. };
  10296. Refs.prototype.ensureBound = function (target, property) {
  10297. if (!hasOwnProperty$1(target, property)) {
  10298. this.bind(target, property);
  10299. }
  10300. };
  10301. Refs.prototype.unset = function (target, property, value) {
  10302. if (target) {
  10303. this.ensureBound(target, property);
  10304. if (property.collection) {
  10305. this.ensureRefsCollection(target, property).remove(value);
  10306. } else {
  10307. target[property.name] = undefined;
  10308. }
  10309. }
  10310. };
  10311. Refs.prototype.set = function (target, property, value) {
  10312. if (target) {
  10313. this.ensureBound(target, property);
  10314. if (property.collection) {
  10315. this.ensureRefsCollection(target, property).add(value);
  10316. } else {
  10317. target[property.name] = value;
  10318. }
  10319. }
  10320. };
  10321. var parentRefs = new Refs({ name: 'children', enumerable: true, collection: true }, { name: 'parent' }),
  10322. labelRefs = new Refs({ name: 'labels', enumerable: true, collection: true }, { name: 'labelTarget' }),
  10323. attacherRefs = new Refs({ name: 'attachers', collection: true }, { name: 'host' }),
  10324. outgoingRefs = new Refs({ name: 'outgoing', collection: true }, { name: 'source' }),
  10325. incomingRefs = new Refs({ name: 'incoming', collection: true }, { name: 'target' });
  10326. /**
  10327. * @typedef {import('./Types').Element} Element
  10328. * @typedef {import('./Types').Shape} Shape
  10329. * @typedef {import('./Types').Root} Root
  10330. * @typedef {import('./Types').Label} Label
  10331. * @typedef {import('./Types').Connection} Connection
  10332. */
  10333. /**
  10334. * The basic graphical representation
  10335. *
  10336. * @class
  10337. * @constructor
  10338. */
  10339. function ElementImpl() {
  10340. /**
  10341. * The object that backs up the shape
  10342. *
  10343. * @name Element#businessObject
  10344. * @type Object
  10345. */
  10346. Object.defineProperty(this, 'businessObject', {
  10347. writable: true
  10348. });
  10349. /**
  10350. * Single label support, will mapped to multi label array
  10351. *
  10352. * @name Element#label
  10353. * @type Object
  10354. */
  10355. Object.defineProperty(this, 'label', {
  10356. get: function() {
  10357. return this.labels[0];
  10358. },
  10359. set: function(newLabel) {
  10360. var label = this.label,
  10361. labels = this.labels;
  10362. if (!newLabel && label) {
  10363. labels.remove(label);
  10364. } else {
  10365. labels.add(newLabel, 0);
  10366. }
  10367. }
  10368. });
  10369. /**
  10370. * The parent shape
  10371. *
  10372. * @name Element#parent
  10373. * @type Shape
  10374. */
  10375. parentRefs.bind(this, 'parent');
  10376. /**
  10377. * The list of labels
  10378. *
  10379. * @name Element#labels
  10380. * @type Label
  10381. */
  10382. labelRefs.bind(this, 'labels');
  10383. /**
  10384. * The list of outgoing connections
  10385. *
  10386. * @name Element#outgoing
  10387. * @type Array<Connection>
  10388. */
  10389. outgoingRefs.bind(this, 'outgoing');
  10390. /**
  10391. * The list of incoming connections
  10392. *
  10393. * @name Element#incoming
  10394. * @type Array<Connection>
  10395. */
  10396. incomingRefs.bind(this, 'incoming');
  10397. }
  10398. /**
  10399. * A graphical object
  10400. *
  10401. * @class
  10402. * @constructor
  10403. *
  10404. * @extends ElementImpl
  10405. */
  10406. function ShapeImpl() {
  10407. ElementImpl.call(this);
  10408. /**
  10409. * Indicates frame shapes
  10410. *
  10411. * @name ShapeImpl#isFrame
  10412. * @type boolean
  10413. */
  10414. /**
  10415. * The list of children
  10416. *
  10417. * @name ShapeImpl#children
  10418. * @type Element[]
  10419. */
  10420. parentRefs.bind(this, 'children');
  10421. /**
  10422. * @name ShapeImpl#host
  10423. * @type Shape
  10424. */
  10425. attacherRefs.bind(this, 'host');
  10426. /**
  10427. * @name ShapeImpl#attachers
  10428. * @type Shape
  10429. */
  10430. attacherRefs.bind(this, 'attachers');
  10431. }
  10432. e(ShapeImpl, ElementImpl);
  10433. /**
  10434. * A root graphical object
  10435. *
  10436. * @class
  10437. * @constructor
  10438. *
  10439. * @extends ElementImpl
  10440. */
  10441. function RootImpl() {
  10442. ElementImpl.call(this);
  10443. /**
  10444. * The list of children
  10445. *
  10446. * @name RootImpl#children
  10447. * @type Element[]
  10448. */
  10449. parentRefs.bind(this, 'children');
  10450. }
  10451. e(RootImpl, ShapeImpl);
  10452. /**
  10453. * A label for an element
  10454. *
  10455. * @class
  10456. * @constructor
  10457. *
  10458. * @extends ShapeImpl
  10459. */
  10460. function LabelImpl() {
  10461. ShapeImpl.call(this);
  10462. /**
  10463. * The labeled element
  10464. *
  10465. * @name LabelImpl#labelTarget
  10466. * @type Element
  10467. */
  10468. labelRefs.bind(this, 'labelTarget');
  10469. }
  10470. e(LabelImpl, ShapeImpl);
  10471. /**
  10472. * A connection between two elements
  10473. *
  10474. * @class
  10475. * @constructor
  10476. *
  10477. * @extends ElementImpl
  10478. */
  10479. function ConnectionImpl() {
  10480. ElementImpl.call(this);
  10481. /**
  10482. * The element this connection originates from
  10483. *
  10484. * @name ConnectionImpl#source
  10485. * @type Element
  10486. */
  10487. outgoingRefs.bind(this, 'source');
  10488. /**
  10489. * The element this connection points to
  10490. *
  10491. * @name ConnectionImpl#target
  10492. * @type Element
  10493. */
  10494. incomingRefs.bind(this, 'target');
  10495. }
  10496. e(ConnectionImpl, ElementImpl);
  10497. var types$6 = {
  10498. connection: ConnectionImpl,
  10499. shape: ShapeImpl,
  10500. label: LabelImpl,
  10501. root: RootImpl
  10502. };
  10503. /**
  10504. * Creates a root element.
  10505. *
  10506. * @overlord
  10507. *
  10508. * @example
  10509. *
  10510. * ```javascript
  10511. * import * as Model from 'diagram-js/lib/model';
  10512. *
  10513. * const root = Model.create('root', {
  10514. * x: 100,
  10515. * y: 100,
  10516. * width: 100,
  10517. * height: 100
  10518. * });
  10519. * ```
  10520. *
  10521. * @param {'root'} type
  10522. * @param {any} [attrs]
  10523. *
  10524. * @return {Root}
  10525. */
  10526. /**
  10527. * Creates a connection.
  10528. *
  10529. * @overlord
  10530. *
  10531. * @example
  10532. *
  10533. * ```javascript
  10534. * import * as Model from 'diagram-js/lib/model';
  10535. *
  10536. * const connection = Model.create('connection', {
  10537. * waypoints: [
  10538. * { x: 100, y: 100 },
  10539. * { x: 200, y: 100 }
  10540. * ]
  10541. * });
  10542. * ```
  10543. *
  10544. * @param {'connection'} type
  10545. * @param {any} [attrs]
  10546. *
  10547. * @return {Connection}
  10548. */
  10549. /**
  10550. * Creates a shape.
  10551. *
  10552. * @overlord
  10553. *
  10554. * @example
  10555. *
  10556. * ```javascript
  10557. * import * as Model from 'diagram-js/lib/model';
  10558. *
  10559. * const shape = Model.create('shape', {
  10560. * x: 100,
  10561. * y: 100,
  10562. * width: 100,
  10563. * height: 100
  10564. * });
  10565. * ```
  10566. *
  10567. * @param {'shape'} type
  10568. * @param {any} [attrs]
  10569. *
  10570. * @return {Shape}
  10571. */
  10572. /**
  10573. * Creates a label.
  10574. *
  10575. * @example
  10576. *
  10577. * ```javascript
  10578. * import * as Model from 'diagram-js/lib/model';
  10579. *
  10580. * const label = Model.create('label', {
  10581. * x: 100,
  10582. * y: 100,
  10583. * width: 100,
  10584. * height: 100,
  10585. * labelTarget: shape
  10586. * });
  10587. * ```
  10588. *
  10589. * @param {'label'} type
  10590. * @param {Object} [attrs]
  10591. *
  10592. * @return {Label}
  10593. */
  10594. function create(type, attrs) {
  10595. var Type = types$6[type];
  10596. if (!Type) {
  10597. throw new Error('unknown type: <' + type + '>');
  10598. }
  10599. return assign$1(new Type(), attrs);
  10600. }
  10601. /**
  10602. * @typedef {import('../model/Types').Element} Element
  10603. * @typedef {import('../model/Types').Connection} Connection
  10604. * @typedef {import('../model/Types').Label} Label
  10605. * @typedef {import('../model/Types').Root} Root
  10606. * @typedef {import('../model/Types').Shape} Shape
  10607. */
  10608. /**
  10609. * A factory for model elements.
  10610. *
  10611. * @template {Connection} [T=Connection]
  10612. * @template {Label} [U=Label]
  10613. * @template {Root} [V=Root]
  10614. * @template {Shape} [W=Shape]
  10615. */
  10616. function ElementFactory() {
  10617. this._uid = 12;
  10618. }
  10619. /**
  10620. * Create a root element.
  10621. *
  10622. * @param {Partial<Root>} [attrs]
  10623. *
  10624. * @return {V} The created root element.
  10625. */
  10626. ElementFactory.prototype.createRoot = function(attrs) {
  10627. return this.create('root', attrs);
  10628. };
  10629. /**
  10630. * Create a label.
  10631. *
  10632. * @param {Partial<Label>} [attrs]
  10633. *
  10634. * @return {U} The created label.
  10635. */
  10636. ElementFactory.prototype.createLabel = function(attrs) {
  10637. return this.create('label', attrs);
  10638. };
  10639. /**
  10640. * Create a shape.
  10641. *
  10642. * @param {Partial<Shape>} [attrs]
  10643. *
  10644. * @return {W} The created shape.
  10645. */
  10646. ElementFactory.prototype.createShape = function(attrs) {
  10647. return this.create('shape', attrs);
  10648. };
  10649. /**
  10650. * Create a connection.
  10651. *
  10652. * @param {Partial<Connection>} [attrs]
  10653. *
  10654. * @return {T} The created connection.
  10655. */
  10656. ElementFactory.prototype.createConnection = function(attrs) {
  10657. return this.create('connection', attrs);
  10658. };
  10659. /**
  10660. * Create a root element.
  10661. *
  10662. * @overlord
  10663. * @param {'root'} type
  10664. * @param {Partial<Root>} [attrs]
  10665. * @return {V}
  10666. */
  10667. /**
  10668. * Create a shape.
  10669. *
  10670. * @overlord
  10671. * @param {'shape'} type
  10672. * @param {Partial<Shape>} [attrs]
  10673. * @return {W}
  10674. */
  10675. /**
  10676. * Create a connection.
  10677. *
  10678. * @overlord
  10679. * @param {'connection'} type
  10680. * @param {Partial<Connection>} [attrs]
  10681. * @return {T}
  10682. */
  10683. /**
  10684. * Create a label.
  10685. *
  10686. * @param {'label'} type
  10687. * @param {Partial<Label>} [attrs]
  10688. * @return {U}
  10689. */
  10690. ElementFactory.prototype.create = function(type, attrs) {
  10691. attrs = assign$1({}, attrs || {});
  10692. if (!attrs.id) {
  10693. attrs.id = type + '_' + (this._uid++);
  10694. }
  10695. return create(type, attrs);
  10696. };
  10697. var FN_REF = '__fn';
  10698. var DEFAULT_PRIORITY = 1000;
  10699. var slice = Array.prototype.slice;
  10700. /**
  10701. * @typedef { {
  10702. * stopPropagation(): void;
  10703. * preventDefault(): void;
  10704. * cancelBubble: boolean;
  10705. * defaultPrevented: boolean;
  10706. * returnValue: any;
  10707. * } } Event
  10708. */
  10709. /**
  10710. * @template E
  10711. *
  10712. * @typedef { (event: E & Event, ...any) => any } EventBusEventCallback
  10713. */
  10714. /**
  10715. * @typedef { {
  10716. * priority: number;
  10717. * next: EventBusListener | null;
  10718. * callback: EventBusEventCallback<any>;
  10719. * } } EventBusListener
  10720. */
  10721. /**
  10722. * A general purpose event bus.
  10723. *
  10724. * This component is used to communicate across a diagram instance.
  10725. * Other parts of a diagram can use it to listen to and broadcast events.
  10726. *
  10727. *
  10728. * ## Registering for Events
  10729. *
  10730. * The event bus provides the {@link EventBus#on} and {@link EventBus#once}
  10731. * methods to register for events. {@link EventBus#off} can be used to
  10732. * remove event registrations. Listeners receive an instance of {@link Event}
  10733. * as the first argument. It allows them to hook into the event execution.
  10734. *
  10735. * ```javascript
  10736. *
  10737. * // listen for event
  10738. * eventBus.on('foo', function(event) {
  10739. *
  10740. * // access event type
  10741. * event.type; // 'foo'
  10742. *
  10743. * // stop propagation to other listeners
  10744. * event.stopPropagation();
  10745. *
  10746. * // prevent event default
  10747. * event.preventDefault();
  10748. * });
  10749. *
  10750. * // listen for event with custom payload
  10751. * eventBus.on('bar', function(event, payload) {
  10752. * console.log(payload);
  10753. * });
  10754. *
  10755. * // listen for event returning value
  10756. * eventBus.on('foobar', function(event) {
  10757. *
  10758. * // stop event propagation + prevent default
  10759. * return false;
  10760. *
  10761. * // stop event propagation + return custom result
  10762. * return {
  10763. * complex: 'listening result'
  10764. * };
  10765. * });
  10766. *
  10767. *
  10768. * // listen with custom priority (default=1000, higher is better)
  10769. * eventBus.on('priorityfoo', 1500, function(event) {
  10770. * console.log('invoked first!');
  10771. * });
  10772. *
  10773. *
  10774. * // listen for event and pass the context (`this`)
  10775. * eventBus.on('foobar', function(event) {
  10776. * this.foo();
  10777. * }, this);
  10778. * ```
  10779. *
  10780. *
  10781. * ## Emitting Events
  10782. *
  10783. * Events can be emitted via the event bus using {@link EventBus#fire}.
  10784. *
  10785. * ```javascript
  10786. *
  10787. * // false indicates that the default action
  10788. * // was prevented by listeners
  10789. * if (eventBus.fire('foo') === false) {
  10790. * console.log('default has been prevented!');
  10791. * };
  10792. *
  10793. *
  10794. * // custom args + return value listener
  10795. * eventBus.on('sum', function(event, a, b) {
  10796. * return a + b;
  10797. * });
  10798. *
  10799. * // you can pass custom arguments + retrieve result values.
  10800. * var sum = eventBus.fire('sum', 1, 2);
  10801. * console.log(sum); // 3
  10802. * ```
  10803. */
  10804. function EventBus() {
  10805. /**
  10806. * @type { Record<string, EventBusListener> }
  10807. */
  10808. this._listeners = {};
  10809. // cleanup on destroy on lowest priority to allow
  10810. // message passing until the bitter end
  10811. this.on('diagram.destroy', 1, this._destroy, this);
  10812. }
  10813. /**
  10814. * Register an event listener for events with the given name.
  10815. *
  10816. * The callback will be invoked with `event, ...additionalArguments`
  10817. * that have been passed to {@link EventBus#fire}.
  10818. *
  10819. * Returning false from a listener will prevent the events default action
  10820. * (if any is specified). To stop an event from being processed further in
  10821. * other listeners execute {@link Event#stopPropagation}.
  10822. *
  10823. * Returning anything but `undefined` from a listener will stop the listener propagation.
  10824. *
  10825. * @template T
  10826. *
  10827. * @param {string|string[]} events to subscribe to
  10828. * @param {number} [priority=1000] listen priority
  10829. * @param {EventBusEventCallback<T>} callback
  10830. * @param {any} [that] callback context
  10831. */
  10832. EventBus.prototype.on = function(events, priority, callback, that) {
  10833. events = isArray$2(events) ? events : [ events ];
  10834. if (isFunction(priority)) {
  10835. that = callback;
  10836. callback = priority;
  10837. priority = DEFAULT_PRIORITY;
  10838. }
  10839. if (!isNumber(priority)) {
  10840. throw new Error('priority must be a number');
  10841. }
  10842. var actualCallback = callback;
  10843. if (that) {
  10844. actualCallback = bind$2(callback, that);
  10845. // make sure we remember and are able to remove
  10846. // bound callbacks via {@link #off} using the original
  10847. // callback
  10848. actualCallback[FN_REF] = callback[FN_REF] || callback;
  10849. }
  10850. var self = this;
  10851. events.forEach(function(e) {
  10852. self._addListener(e, {
  10853. priority: priority,
  10854. callback: actualCallback,
  10855. next: null
  10856. });
  10857. });
  10858. };
  10859. /**
  10860. * Register an event listener that is called only once.
  10861. *
  10862. * @template T
  10863. *
  10864. * @param {string|string[]} events to subscribe to
  10865. * @param {number} [priority=1000] the listen priority
  10866. * @param {EventBusEventCallback<T>} callback
  10867. * @param {any} [that] callback context
  10868. */
  10869. EventBus.prototype.once = function(events, priority, callback, that) {
  10870. var self = this;
  10871. if (isFunction(priority)) {
  10872. that = callback;
  10873. callback = priority;
  10874. priority = DEFAULT_PRIORITY;
  10875. }
  10876. if (!isNumber(priority)) {
  10877. throw new Error('priority must be a number');
  10878. }
  10879. function wrappedCallback() {
  10880. wrappedCallback.__isTomb = true;
  10881. var result = callback.apply(that, arguments);
  10882. self.off(events, wrappedCallback);
  10883. return result;
  10884. }
  10885. // make sure we remember and are able to remove
  10886. // bound callbacks via {@link #off} using the original
  10887. // callback
  10888. wrappedCallback[FN_REF] = callback;
  10889. this.on(events, priority, wrappedCallback);
  10890. };
  10891. /**
  10892. * Removes event listeners by event and callback.
  10893. *
  10894. * If no callback is given, all listeners for a given event name are being removed.
  10895. *
  10896. * @param {string|string[]} events
  10897. * @param {EventBusEventCallback} [callback]
  10898. */
  10899. EventBus.prototype.off = function(events, callback) {
  10900. events = isArray$2(events) ? events : [ events ];
  10901. var self = this;
  10902. events.forEach(function(event) {
  10903. self._removeListener(event, callback);
  10904. });
  10905. };
  10906. /**
  10907. * Create an event recognized be the event bus.
  10908. *
  10909. * @param {Object} data Event data.
  10910. *
  10911. * @return {Event} An event that will be recognized by the event bus.
  10912. */
  10913. EventBus.prototype.createEvent = function(data) {
  10914. var event = new InternalEvent();
  10915. event.init(data);
  10916. return event;
  10917. };
  10918. /**
  10919. * Fires an event.
  10920. *
  10921. * @example
  10922. *
  10923. * ```javascript
  10924. * // fire event by name
  10925. * events.fire('foo');
  10926. *
  10927. * // fire event object with nested type
  10928. * var event = { type: 'foo' };
  10929. * events.fire(event);
  10930. *
  10931. * // fire event with explicit type
  10932. * var event = { x: 10, y: 20 };
  10933. * events.fire('element.moved', event);
  10934. *
  10935. * // pass additional arguments to the event
  10936. * events.on('foo', function(event, bar) {
  10937. * alert(bar);
  10938. * });
  10939. *
  10940. * events.fire({ type: 'foo' }, 'I am bar!');
  10941. * ```
  10942. *
  10943. * @param {string} [type] event type
  10944. * @param {Object} [data] event or event data
  10945. * @param {...any} [args] additional arguments the callback will be called with.
  10946. *
  10947. * @return {any} The return value. Will be set to `false` if the default was prevented.
  10948. */
  10949. EventBus.prototype.fire = function(type, data) {
  10950. var event,
  10951. firstListener,
  10952. returnValue,
  10953. args;
  10954. args = slice.call(arguments);
  10955. if (typeof type === 'object') {
  10956. data = type;
  10957. type = data.type;
  10958. }
  10959. if (!type) {
  10960. throw new Error('no event type specified');
  10961. }
  10962. firstListener = this._listeners[type];
  10963. if (!firstListener) {
  10964. return;
  10965. }
  10966. // we make sure we fire instances of our home made
  10967. // events here. We wrap them only once, though
  10968. if (data instanceof InternalEvent) {
  10969. // we are fine, we alread have an event
  10970. event = data;
  10971. } else {
  10972. event = this.createEvent(data);
  10973. }
  10974. // ensure we pass the event as the first parameter
  10975. args[0] = event;
  10976. // original event type (in case we delegate)
  10977. var originalType = event.type;
  10978. // update event type before delegation
  10979. if (type !== originalType) {
  10980. event.type = type;
  10981. }
  10982. try {
  10983. returnValue = this._invokeListeners(event, args, firstListener);
  10984. } finally {
  10985. // reset event type after delegation
  10986. if (type !== originalType) {
  10987. event.type = originalType;
  10988. }
  10989. }
  10990. // set the return value to false if the event default
  10991. // got prevented and no other return value exists
  10992. if (returnValue === undefined && event.defaultPrevented) {
  10993. returnValue = false;
  10994. }
  10995. return returnValue;
  10996. };
  10997. /**
  10998. * Handle an error by firing an event.
  10999. *
  11000. * @param {Error} error The error to be handled.
  11001. *
  11002. * @return {boolean} Whether the error was handled.
  11003. */
  11004. EventBus.prototype.handleError = function(error) {
  11005. return this.fire('error', { error: error }) === false;
  11006. };
  11007. EventBus.prototype._destroy = function() {
  11008. this._listeners = {};
  11009. };
  11010. /**
  11011. * @param {Event} event
  11012. * @param {any[]} args
  11013. * @param {EventBusListener} listener
  11014. *
  11015. * @return {any}
  11016. */
  11017. EventBus.prototype._invokeListeners = function(event, args, listener) {
  11018. var returnValue;
  11019. while (listener) {
  11020. // handle stopped propagation
  11021. if (event.cancelBubble) {
  11022. break;
  11023. }
  11024. returnValue = this._invokeListener(event, args, listener);
  11025. listener = listener.next;
  11026. }
  11027. return returnValue;
  11028. };
  11029. /**
  11030. * @param {Event} event
  11031. * @param {any[]} args
  11032. * @param {EventBusListener} listener
  11033. *
  11034. * @return {any}
  11035. */
  11036. EventBus.prototype._invokeListener = function(event, args, listener) {
  11037. var returnValue;
  11038. if (listener.callback.__isTomb) {
  11039. return returnValue;
  11040. }
  11041. try {
  11042. // returning false prevents the default action
  11043. returnValue = invokeFunction(listener.callback, args);
  11044. // stop propagation on return value
  11045. if (returnValue !== undefined) {
  11046. event.returnValue = returnValue;
  11047. event.stopPropagation();
  11048. }
  11049. // prevent default on return false
  11050. if (returnValue === false) {
  11051. event.preventDefault();
  11052. }
  11053. } catch (error) {
  11054. if (!this.handleError(error)) {
  11055. console.error('unhandled error in event listener', error);
  11056. throw error;
  11057. }
  11058. }
  11059. return returnValue;
  11060. };
  11061. /**
  11062. * Add new listener with a certain priority to the list
  11063. * of listeners (for the given event).
  11064. *
  11065. * The semantics of listener registration / listener execution are
  11066. * first register, first serve: New listeners will always be inserted
  11067. * after existing listeners with the same priority.
  11068. *
  11069. * Example: Inserting two listeners with priority 1000 and 1300
  11070. *
  11071. * * before: [ 1500, 1500, 1000, 1000 ]
  11072. * * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ]
  11073. *
  11074. * @param {string} event
  11075. * @param {EventBusListener} newListener
  11076. */
  11077. EventBus.prototype._addListener = function(event, newListener) {
  11078. var listener = this._getListeners(event),
  11079. previousListener;
  11080. // no prior listeners
  11081. if (!listener) {
  11082. this._setListeners(event, newListener);
  11083. return;
  11084. }
  11085. // ensure we order listeners by priority from
  11086. // 0 (high) to n > 0 (low)
  11087. while (listener) {
  11088. if (listener.priority < newListener.priority) {
  11089. newListener.next = listener;
  11090. if (previousListener) {
  11091. previousListener.next = newListener;
  11092. } else {
  11093. this._setListeners(event, newListener);
  11094. }
  11095. return;
  11096. }
  11097. previousListener = listener;
  11098. listener = listener.next;
  11099. }
  11100. // add new listener to back
  11101. previousListener.next = newListener;
  11102. };
  11103. /**
  11104. * @param {string} name
  11105. *
  11106. * @return {EventBusListener}
  11107. */
  11108. EventBus.prototype._getListeners = function(name) {
  11109. return this._listeners[name];
  11110. };
  11111. /**
  11112. * @param {string} name
  11113. * @param {EventBusListener} listener
  11114. */
  11115. EventBus.prototype._setListeners = function(name, listener) {
  11116. this._listeners[name] = listener;
  11117. };
  11118. EventBus.prototype._removeListener = function(event, callback) {
  11119. var listener = this._getListeners(event),
  11120. nextListener,
  11121. previousListener,
  11122. listenerCallback;
  11123. if (!callback) {
  11124. // clear listeners
  11125. this._setListeners(event, null);
  11126. return;
  11127. }
  11128. while (listener) {
  11129. nextListener = listener.next;
  11130. listenerCallback = listener.callback;
  11131. if (listenerCallback === callback || listenerCallback[FN_REF] === callback) {
  11132. if (previousListener) {
  11133. previousListener.next = nextListener;
  11134. } else {
  11135. // new first listener
  11136. this._setListeners(event, nextListener);
  11137. }
  11138. }
  11139. previousListener = listener;
  11140. listener = nextListener;
  11141. }
  11142. };
  11143. /**
  11144. * A event that is emitted via the event bus.
  11145. */
  11146. function InternalEvent() { }
  11147. InternalEvent.prototype.stopPropagation = function() {
  11148. this.cancelBubble = true;
  11149. };
  11150. InternalEvent.prototype.preventDefault = function() {
  11151. this.defaultPrevented = true;
  11152. };
  11153. InternalEvent.prototype.init = function(data) {
  11154. assign$1(this, data || {});
  11155. };
  11156. /**
  11157. * Invoke function. Be fast...
  11158. *
  11159. * @param {Function} fn
  11160. * @param {any[]} args
  11161. *
  11162. * @return {any}
  11163. */
  11164. function invokeFunction(fn, args) {
  11165. return fn.apply(null, args);
  11166. }
  11167. /**
  11168. * SVGs for elements are generated by the {@link GraphicsFactory}.
  11169. *
  11170. * This utility gives quick access to the important semantic
  11171. * parts of an element.
  11172. */
  11173. /**
  11174. * Returns the visual part of a diagram element.
  11175. *
  11176. * @param {SVGElement} gfx
  11177. *
  11178. * @return {SVGElement}
  11179. */
  11180. function getVisual(gfx) {
  11181. return gfx.childNodes[0];
  11182. }
  11183. /**
  11184. * Returns the children for a given diagram element.
  11185. *
  11186. * @param {SVGElement} gfx
  11187. * @return {SVGElement}
  11188. */
  11189. function getChildren(gfx) {
  11190. return gfx.parentNode.childNodes[1];
  11191. }
  11192. /**
  11193. * @typedef {import('./Types').ConnectionLike} ConnectionLike
  11194. * @typedef {import('./Types').ElementLike} ElementLike
  11195. * @typedef {import('./Types').ShapeLike} ShapeLike
  11196. *
  11197. * @typedef {import('./ElementRegistry').default} ElementRegistry
  11198. * @typedef {import('./EventBus').default} EventBus
  11199. */
  11200. /**
  11201. * A factory that creates graphical elements.
  11202. *
  11203. * @param {EventBus} eventBus
  11204. * @param {ElementRegistry} elementRegistry
  11205. */
  11206. function GraphicsFactory(eventBus, elementRegistry) {
  11207. this._eventBus = eventBus;
  11208. this._elementRegistry = elementRegistry;
  11209. }
  11210. GraphicsFactory.$inject = [ 'eventBus' , 'elementRegistry' ];
  11211. /**
  11212. * @param { { parent?: any } } element
  11213. * @return {SVGElement}
  11214. */
  11215. GraphicsFactory.prototype._getChildrenContainer = function(element) {
  11216. var gfx = this._elementRegistry.getGraphics(element);
  11217. var childrenGfx;
  11218. // root element
  11219. if (!element.parent) {
  11220. childrenGfx = gfx;
  11221. } else {
  11222. childrenGfx = getChildren(gfx);
  11223. if (!childrenGfx) {
  11224. childrenGfx = create$1('g');
  11225. classes$1(childrenGfx).add('djs-children');
  11226. append(gfx.parentNode, childrenGfx);
  11227. }
  11228. }
  11229. return childrenGfx;
  11230. };
  11231. /**
  11232. * Clears the graphical representation of the element and returns the
  11233. * cleared visual (the <g class="djs-visual" /> element).
  11234. */
  11235. GraphicsFactory.prototype._clear = function(gfx) {
  11236. var visual = getVisual(gfx);
  11237. clear(visual);
  11238. return visual;
  11239. };
  11240. /**
  11241. * Creates a gfx container for shapes and connections
  11242. *
  11243. * The layout is as follows:
  11244. *
  11245. * <g class="djs-group">
  11246. *
  11247. * <!-- the gfx -->
  11248. * <g class="djs-element djs-(shape|connection|frame)">
  11249. * <g class="djs-visual">
  11250. * <!-- the renderer draws in here -->
  11251. * </g>
  11252. *
  11253. * <!-- extensions (overlays, click box, ...) goes here
  11254. * </g>
  11255. *
  11256. * <!-- the gfx child nodes -->
  11257. * <g class="djs-children"></g>
  11258. * </g>
  11259. *
  11260. * @param {string} type the type of the element, i.e. shape | connection
  11261. * @param {SVGElement} childrenGfx
  11262. * @param {number} [parentIndex] position to create container in parent
  11263. * @param {boolean} [isFrame] is frame element
  11264. *
  11265. * @return {SVGElement}
  11266. */
  11267. GraphicsFactory.prototype._createContainer = function(
  11268. type, childrenGfx, parentIndex, isFrame
  11269. ) {
  11270. var outerGfx = create$1('g');
  11271. classes$1(outerGfx).add('djs-group');
  11272. // insert node at position
  11273. if (typeof parentIndex !== 'undefined') {
  11274. prependTo(outerGfx, childrenGfx, childrenGfx.childNodes[parentIndex]);
  11275. } else {
  11276. append(childrenGfx, outerGfx);
  11277. }
  11278. var gfx = create$1('g');
  11279. classes$1(gfx).add('djs-element');
  11280. classes$1(gfx).add('djs-' + type);
  11281. if (isFrame) {
  11282. classes$1(gfx).add('djs-frame');
  11283. }
  11284. append(outerGfx, gfx);
  11285. // create visual
  11286. var visual = create$1('g');
  11287. classes$1(visual).add('djs-visual');
  11288. append(gfx, visual);
  11289. return gfx;
  11290. };
  11291. /**
  11292. * Create a graphical element.
  11293. *
  11294. * @param { 'shape' | 'connection' | 'label' | 'root' } type The type of the element.
  11295. * @param {ElementLike} element The element.
  11296. * @param {number} [parentIndex] The index at which to add the graphical element to its parent's children.
  11297. *
  11298. * @return {SVGElement} The graphical element.
  11299. */
  11300. GraphicsFactory.prototype.create = function(type, element, parentIndex) {
  11301. var childrenGfx = this._getChildrenContainer(element.parent);
  11302. return this._createContainer(type, childrenGfx, parentIndex, isFrameElement(element));
  11303. };
  11304. /**
  11305. * Update the containments of the given elements.
  11306. *
  11307. * @param {ElementLike[]} elements The elements.
  11308. */
  11309. GraphicsFactory.prototype.updateContainments = function(elements) {
  11310. var self = this,
  11311. elementRegistry = this._elementRegistry,
  11312. parents;
  11313. parents = reduce(elements, function(map, e) {
  11314. if (e.parent) {
  11315. map[e.parent.id] = e.parent;
  11316. }
  11317. return map;
  11318. }, {});
  11319. // update all parents of changed and reorganized their children
  11320. // in the correct order (as indicated in our model)
  11321. forEach$1(parents, function(parent) {
  11322. var children = parent.children;
  11323. if (!children) {
  11324. return;
  11325. }
  11326. var childrenGfx = self._getChildrenContainer(parent);
  11327. forEach$1(children.slice().reverse(), function(child) {
  11328. var childGfx = elementRegistry.getGraphics(child);
  11329. prependTo(childGfx.parentNode, childrenGfx);
  11330. });
  11331. });
  11332. };
  11333. /**
  11334. * Draw a shape.
  11335. *
  11336. * @param {SVGElement} visual The graphical element.
  11337. * @param {ShapeLike} element The shape.
  11338. * @param {Object} attrs Optional attributes.
  11339. *
  11340. * @return {SVGElement}
  11341. */
  11342. GraphicsFactory.prototype.drawShape = function(visual, element, attrs = {}) {
  11343. var eventBus = this._eventBus;
  11344. return eventBus.fire('render.shape', { gfx: visual, element, attrs });
  11345. };
  11346. /**
  11347. * Get the path of a shape.
  11348. *
  11349. * @param {ShapeLike} element The shape.
  11350. *
  11351. * @return {string} The path of the shape.
  11352. */
  11353. GraphicsFactory.prototype.getShapePath = function(element) {
  11354. var eventBus = this._eventBus;
  11355. return eventBus.fire('render.getShapePath', element);
  11356. };
  11357. /**
  11358. * Draw a connection.
  11359. *
  11360. * @param {SVGElement} visual The graphical element.
  11361. * @param {ConnectionLike} element The connection.
  11362. * @param {Object} attrs Optional attributes.
  11363. *
  11364. * @return {SVGElement}
  11365. */
  11366. GraphicsFactory.prototype.drawConnection = function(visual, element, attrs = {}) {
  11367. var eventBus = this._eventBus;
  11368. return eventBus.fire('render.connection', { gfx: visual, element, attrs });
  11369. };
  11370. /**
  11371. * Get the path of a connection.
  11372. *
  11373. * @param {ConnectionLike} connection The connection.
  11374. *
  11375. * @return {string} The path of the connection.
  11376. */
  11377. GraphicsFactory.prototype.getConnectionPath = function(connection) {
  11378. var eventBus = this._eventBus;
  11379. return eventBus.fire('render.getConnectionPath', connection);
  11380. };
  11381. /**
  11382. * Update an elements graphical representation.
  11383. *
  11384. * @param {'shape'|'connection'} type
  11385. * @param {ElementLike} element
  11386. * @param {SVGElement} gfx
  11387. */
  11388. GraphicsFactory.prototype.update = function(type, element, gfx) {
  11389. // do NOT update root element
  11390. if (!element.parent) {
  11391. return;
  11392. }
  11393. var visual = this._clear(gfx);
  11394. // redraw
  11395. if (type === 'shape') {
  11396. this.drawShape(visual, element);
  11397. // update positioning
  11398. translate$1(gfx, element.x, element.y);
  11399. } else
  11400. if (type === 'connection') {
  11401. this.drawConnection(visual, element);
  11402. } else {
  11403. throw new Error('unknown type: ' + type);
  11404. }
  11405. if (element.hidden) {
  11406. attr$1(gfx, 'display', 'none');
  11407. } else {
  11408. attr$1(gfx, 'display', 'block');
  11409. }
  11410. };
  11411. /**
  11412. * Remove a graphical element.
  11413. *
  11414. * @param {ElementLike} element The element.
  11415. */
  11416. GraphicsFactory.prototype.remove = function(element) {
  11417. var gfx = this._elementRegistry.getGraphics(element);
  11418. // remove
  11419. remove$2(gfx.parentNode);
  11420. };
  11421. // helpers //////////
  11422. function prependTo(newNode, parentNode, siblingNode) {
  11423. var node = siblingNode || parentNode.firstChild;
  11424. // do not prepend node to itself to prevent IE from crashing
  11425. // https://github.com/bpmn-io/bpmn-js/issues/746
  11426. if (newNode === node) {
  11427. return;
  11428. }
  11429. parentNode.insertBefore(newNode, node);
  11430. }
  11431. /**
  11432. * @type { import('didi').ModuleDeclaration }
  11433. */
  11434. var CoreModule = {
  11435. __depends__: [ DrawModule ],
  11436. __init__: [ 'canvas' ],
  11437. canvas: [ 'type', Canvas ],
  11438. elementRegistry: [ 'type', ElementRegistry ],
  11439. elementFactory: [ 'type', ElementFactory ],
  11440. eventBus: [ 'type', EventBus ],
  11441. graphicsFactory: [ 'type', GraphicsFactory ]
  11442. };
  11443. /**
  11444. * @typedef {import('didi').InjectionContext} InjectionContext
  11445. * @typedef {import('didi').LocalsMap} LocalsMap
  11446. * @typedef {import('didi').ModuleDeclaration} ModuleDeclaration
  11447. *
  11448. * @typedef { {
  11449. * modules?: ModuleDeclaration[];
  11450. * } & Record<string, any> } DiagramOptions
  11451. */
  11452. /**
  11453. * Bootstrap an injector from a list of modules, instantiating a number of default components
  11454. *
  11455. * @param {ModuleDeclaration[]} modules
  11456. *
  11457. * @return {Injector} a injector to use to access the components
  11458. */
  11459. function bootstrap(modules) {
  11460. var injector = new Injector(modules);
  11461. injector.init();
  11462. return injector;
  11463. }
  11464. /**
  11465. * Creates an injector from passed options.
  11466. *
  11467. * @param {DiagramOptions} [options]
  11468. *
  11469. * @return {Injector}
  11470. */
  11471. function createInjector(options) {
  11472. options = options || {};
  11473. /**
  11474. * @type { ModuleDeclaration }
  11475. */
  11476. var configModule = {
  11477. 'config': [ 'value', options ]
  11478. };
  11479. var modules = [ configModule, CoreModule ].concat(options.modules || []);
  11480. return bootstrap(modules);
  11481. }
  11482. /**
  11483. * The main diagram-js entry point that bootstraps the diagram with the given
  11484. * configuration.
  11485. *
  11486. * To register extensions with the diagram, pass them as Array<Module> to the constructor.
  11487. *
  11488. * @class
  11489. * @constructor
  11490. *
  11491. * @example Creating a plug-in that logs whenever a shape is added to the canvas.
  11492. *
  11493. * ```javascript
  11494. * // plug-in implementation
  11495. * function MyLoggingPlugin(eventBus) {
  11496. * eventBus.on('shape.added', function(event) {
  11497. * console.log('shape ', event.shape, ' was added to the diagram');
  11498. * });
  11499. * }
  11500. *
  11501. * // export as module
  11502. * export default {
  11503. * __init__: [ 'myLoggingPlugin' ],
  11504. * myLoggingPlugin: [ 'type', MyLoggingPlugin ]
  11505. * };
  11506. * ```
  11507. *
  11508. * Use the plug-in in a Diagram instance:
  11509. *
  11510. * ```javascript
  11511. * import MyLoggingModule from 'path-to-my-logging-plugin';
  11512. *
  11513. * var diagram = new Diagram({
  11514. * modules: [
  11515. * MyLoggingModule
  11516. * ]
  11517. * });
  11518. *
  11519. * diagram.invoke([ 'canvas', function(canvas) {
  11520. * // add shape to drawing canvas
  11521. * canvas.addShape({ x: 10, y: 10 });
  11522. * });
  11523. *
  11524. * // 'shape ... was added to the diagram' logged to console
  11525. * ```
  11526. *
  11527. * @param {DiagramOptions} [options]
  11528. * @param {Injector} [injector] An (optional) injector to bootstrap the diagram with.
  11529. */
  11530. function Diagram(options, injector) {
  11531. this._injector = injector = injector || createInjector(options);
  11532. // API
  11533. /**
  11534. * Resolves a diagram service.
  11535. *
  11536. * @template T
  11537. *
  11538. * @param {string} name The name of the service to get.
  11539. * @param {boolean} [strict=true] If false, resolve missing services to null.
  11540. *
  11541. * @return {T|null}
  11542. */
  11543. this.get = injector.get;
  11544. /**
  11545. * Executes a function with its dependencies injected.
  11546. *
  11547. * @template T
  11548. *
  11549. * @param {Function} func function to be invoked
  11550. * @param {InjectionContext} [context] context of the invocation
  11551. * @param {LocalsMap} [locals] locals provided
  11552. *
  11553. * @return {T|null}
  11554. */
  11555. this.invoke = injector.invoke;
  11556. // init
  11557. // indicate via event
  11558. /**
  11559. * An event indicating that all plug-ins are loaded.
  11560. *
  11561. * Use this event to fire other events to interested plug-ins
  11562. *
  11563. * @memberOf Diagram
  11564. *
  11565. * @event diagram.init
  11566. *
  11567. * @example
  11568. *
  11569. * ```javascript
  11570. * eventBus.on('diagram.init', function() {
  11571. * eventBus.fire('my-custom-event', { foo: 'BAR' });
  11572. * });
  11573. * ```
  11574. *
  11575. * @type {Object}
  11576. */
  11577. this.get('eventBus').fire('diagram.init');
  11578. }
  11579. /**
  11580. * Destroys the diagram
  11581. */
  11582. Diagram.prototype.destroy = function() {
  11583. this.get('eventBus').fire('diagram.destroy');
  11584. };
  11585. /**
  11586. * Clear the diagram, removing all contents.
  11587. */
  11588. Diagram.prototype.clear = function() {
  11589. this.get('eventBus').fire('diagram.clear');
  11590. };
  11591. /**
  11592. * Moddle base element.
  11593. */
  11594. function Base() { }
  11595. Base.prototype.get = function(name) {
  11596. return this.$model.properties.get(this, name);
  11597. };
  11598. Base.prototype.set = function(name, value) {
  11599. this.$model.properties.set(this, name, value);
  11600. };
  11601. /**
  11602. * A model element factory.
  11603. *
  11604. * @param {Moddle} model
  11605. * @param {Properties} properties
  11606. */
  11607. function Factory(model, properties) {
  11608. this.model = model;
  11609. this.properties = properties;
  11610. }
  11611. Factory.prototype.createType = function(descriptor) {
  11612. var model = this.model;
  11613. var props = this.properties,
  11614. prototype = Object.create(Base.prototype);
  11615. // initialize default values
  11616. forEach$1(descriptor.properties, function(p) {
  11617. if (!p.isMany && p.default !== undefined) {
  11618. prototype[p.name] = p.default;
  11619. }
  11620. });
  11621. props.defineModel(prototype, model);
  11622. props.defineDescriptor(prototype, descriptor);
  11623. var name = descriptor.ns.name;
  11624. /**
  11625. * The new type constructor
  11626. */
  11627. function ModdleElement(attrs) {
  11628. props.define(this, '$type', { value: name, enumerable: true });
  11629. props.define(this, '$attrs', { value: {} });
  11630. props.define(this, '$parent', { writable: true });
  11631. forEach$1(attrs, bind$2(function(val, key) {
  11632. this.set(key, val);
  11633. }, this));
  11634. }
  11635. ModdleElement.prototype = prototype;
  11636. ModdleElement.hasType = prototype.$instanceOf = this.model.hasType;
  11637. // static links
  11638. props.defineModel(ModdleElement, model);
  11639. props.defineDescriptor(ModdleElement, descriptor);
  11640. return ModdleElement;
  11641. };
  11642. /**
  11643. * Built-in moddle types
  11644. */
  11645. var BUILTINS = {
  11646. String: true,
  11647. Boolean: true,
  11648. Integer: true,
  11649. Real: true,
  11650. Element: true
  11651. };
  11652. /**
  11653. * Converters for built in types from string representations
  11654. */
  11655. var TYPE_CONVERTERS = {
  11656. String: function(s) { return s; },
  11657. Boolean: function(s) { return s === 'true'; },
  11658. Integer: function(s) { return parseInt(s, 10); },
  11659. Real: function(s) { return parseFloat(s); }
  11660. };
  11661. /**
  11662. * Convert a type to its real representation
  11663. */
  11664. function coerceType(type, value) {
  11665. var converter = TYPE_CONVERTERS[type];
  11666. if (converter) {
  11667. return converter(value);
  11668. } else {
  11669. return value;
  11670. }
  11671. }
  11672. /**
  11673. * Return whether the given type is built-in
  11674. */
  11675. function isBuiltIn(type) {
  11676. return !!BUILTINS[type];
  11677. }
  11678. /**
  11679. * Return whether the given type is simple
  11680. */
  11681. function isSimple(type) {
  11682. return !!TYPE_CONVERTERS[type];
  11683. }
  11684. /**
  11685. * Parses a namespaced attribute name of the form (ns:)localName to an object,
  11686. * given a default prefix to assume in case no explicit namespace is given.
  11687. *
  11688. * @param {String} name
  11689. * @param {String} [defaultPrefix] the default prefix to take, if none is present.
  11690. *
  11691. * @return {Object} the parsed name
  11692. */
  11693. function parseName(name, defaultPrefix) {
  11694. var parts = name.split(/:/),
  11695. localName, prefix;
  11696. // no prefix (i.e. only local name)
  11697. if (parts.length === 1) {
  11698. localName = name;
  11699. prefix = defaultPrefix;
  11700. } else
  11701. // prefix + local name
  11702. if (parts.length === 2) {
  11703. localName = parts[1];
  11704. prefix = parts[0];
  11705. } else {
  11706. throw new Error('expected <prefix:localName> or <localName>, got ' + name);
  11707. }
  11708. name = (prefix ? prefix + ':' : '') + localName;
  11709. return {
  11710. name: name,
  11711. prefix: prefix,
  11712. localName: localName
  11713. };
  11714. }
  11715. /**
  11716. * A utility to build element descriptors.
  11717. */
  11718. function DescriptorBuilder(nameNs) {
  11719. this.ns = nameNs;
  11720. this.name = nameNs.name;
  11721. this.allTypes = [];
  11722. this.allTypesByName = {};
  11723. this.properties = [];
  11724. this.propertiesByName = {};
  11725. }
  11726. DescriptorBuilder.prototype.build = function() {
  11727. return pick(this, [
  11728. 'ns',
  11729. 'name',
  11730. 'allTypes',
  11731. 'allTypesByName',
  11732. 'properties',
  11733. 'propertiesByName',
  11734. 'bodyProperty',
  11735. 'idProperty'
  11736. ]);
  11737. };
  11738. /**
  11739. * Add property at given index.
  11740. *
  11741. * @param {Object} p
  11742. * @param {Number} [idx]
  11743. * @param {Boolean} [validate=true]
  11744. */
  11745. DescriptorBuilder.prototype.addProperty = function(p, idx, validate) {
  11746. if (typeof idx === 'boolean') {
  11747. validate = idx;
  11748. idx = undefined;
  11749. }
  11750. this.addNamedProperty(p, validate !== false);
  11751. var properties = this.properties;
  11752. if (idx !== undefined) {
  11753. properties.splice(idx, 0, p);
  11754. } else {
  11755. properties.push(p);
  11756. }
  11757. };
  11758. DescriptorBuilder.prototype.replaceProperty = function(oldProperty, newProperty, replace) {
  11759. var oldNameNs = oldProperty.ns;
  11760. var props = this.properties,
  11761. propertiesByName = this.propertiesByName,
  11762. rename = oldProperty.name !== newProperty.name;
  11763. if (oldProperty.isId) {
  11764. if (!newProperty.isId) {
  11765. throw new Error(
  11766. 'property <' + newProperty.ns.name + '> must be id property ' +
  11767. 'to refine <' + oldProperty.ns.name + '>');
  11768. }
  11769. this.setIdProperty(newProperty, false);
  11770. }
  11771. if (oldProperty.isBody) {
  11772. if (!newProperty.isBody) {
  11773. throw new Error(
  11774. 'property <' + newProperty.ns.name + '> must be body property ' +
  11775. 'to refine <' + oldProperty.ns.name + '>');
  11776. }
  11777. // TODO: Check compatibility
  11778. this.setBodyProperty(newProperty, false);
  11779. }
  11780. // validate existence and get location of old property
  11781. var idx = props.indexOf(oldProperty);
  11782. if (idx === -1) {
  11783. throw new Error('property <' + oldNameNs.name + '> not found in property list');
  11784. }
  11785. // remove old property
  11786. props.splice(idx, 1);
  11787. // replacing the named property is intentional
  11788. //
  11789. // * validate only if this is a "rename" operation
  11790. // * add at specific index unless we "replace"
  11791. //
  11792. this.addProperty(newProperty, replace ? undefined : idx, rename);
  11793. // make new property available under old name
  11794. propertiesByName[oldNameNs.name] = propertiesByName[oldNameNs.localName] = newProperty;
  11795. };
  11796. DescriptorBuilder.prototype.redefineProperty = function(p, targetPropertyName, replace) {
  11797. var nsPrefix = p.ns.prefix;
  11798. var parts = targetPropertyName.split('#');
  11799. var name = parseName(parts[0], nsPrefix);
  11800. var attrName = parseName(parts[1], name.prefix).name;
  11801. var redefinedProperty = this.propertiesByName[attrName];
  11802. if (!redefinedProperty) {
  11803. throw new Error('refined property <' + attrName + '> not found');
  11804. } else {
  11805. this.replaceProperty(redefinedProperty, p, replace);
  11806. }
  11807. delete p.redefines;
  11808. };
  11809. DescriptorBuilder.prototype.addNamedProperty = function(p, validate) {
  11810. var ns = p.ns,
  11811. propsByName = this.propertiesByName;
  11812. if (validate) {
  11813. this.assertNotDefined(p, ns.name);
  11814. this.assertNotDefined(p, ns.localName);
  11815. }
  11816. propsByName[ns.name] = propsByName[ns.localName] = p;
  11817. };
  11818. DescriptorBuilder.prototype.removeNamedProperty = function(p) {
  11819. var ns = p.ns,
  11820. propsByName = this.propertiesByName;
  11821. delete propsByName[ns.name];
  11822. delete propsByName[ns.localName];
  11823. };
  11824. DescriptorBuilder.prototype.setBodyProperty = function(p, validate) {
  11825. if (validate && this.bodyProperty) {
  11826. throw new Error(
  11827. 'body property defined multiple times ' +
  11828. '(<' + this.bodyProperty.ns.name + '>, <' + p.ns.name + '>)');
  11829. }
  11830. this.bodyProperty = p;
  11831. };
  11832. DescriptorBuilder.prototype.setIdProperty = function(p, validate) {
  11833. if (validate && this.idProperty) {
  11834. throw new Error(
  11835. 'id property defined multiple times ' +
  11836. '(<' + this.idProperty.ns.name + '>, <' + p.ns.name + '>)');
  11837. }
  11838. this.idProperty = p;
  11839. };
  11840. DescriptorBuilder.prototype.assertNotTrait = function(typeDescriptor) {
  11841. const _extends = typeDescriptor.extends || [];
  11842. if (_extends.length) {
  11843. throw new Error(
  11844. `cannot create <${ typeDescriptor.name }> extending <${ typeDescriptor.extends }>`
  11845. );
  11846. }
  11847. };
  11848. DescriptorBuilder.prototype.assertNotDefined = function(p, name) {
  11849. var propertyName = p.name,
  11850. definedProperty = this.propertiesByName[propertyName];
  11851. if (definedProperty) {
  11852. throw new Error(
  11853. 'property <' + propertyName + '> already defined; ' +
  11854. 'override of <' + definedProperty.definedBy.ns.name + '#' + definedProperty.ns.name + '> by ' +
  11855. '<' + p.definedBy.ns.name + '#' + p.ns.name + '> not allowed without redefines');
  11856. }
  11857. };
  11858. DescriptorBuilder.prototype.hasProperty = function(name) {
  11859. return this.propertiesByName[name];
  11860. };
  11861. DescriptorBuilder.prototype.addTrait = function(t, inherited) {
  11862. if (inherited) {
  11863. this.assertNotTrait(t);
  11864. }
  11865. var typesByName = this.allTypesByName,
  11866. types = this.allTypes;
  11867. var typeName = t.name;
  11868. if (typeName in typesByName) {
  11869. return;
  11870. }
  11871. forEach$1(t.properties, bind$2(function(p) {
  11872. // clone property to allow extensions
  11873. p = assign$1({}, p, {
  11874. name: p.ns.localName,
  11875. inherited: inherited
  11876. });
  11877. Object.defineProperty(p, 'definedBy', {
  11878. value: t
  11879. });
  11880. var replaces = p.replaces,
  11881. redefines = p.redefines;
  11882. // add replace/redefine support
  11883. if (replaces || redefines) {
  11884. this.redefineProperty(p, replaces || redefines, replaces);
  11885. } else {
  11886. if (p.isBody) {
  11887. this.setBodyProperty(p);
  11888. }
  11889. if (p.isId) {
  11890. this.setIdProperty(p);
  11891. }
  11892. this.addProperty(p);
  11893. }
  11894. }, this));
  11895. types.push(t);
  11896. typesByName[typeName] = t;
  11897. };
  11898. /**
  11899. * A registry of Moddle packages.
  11900. *
  11901. * @param {Array<Package>} packages
  11902. * @param {Properties} properties
  11903. */
  11904. function Registry(packages, properties) {
  11905. this.packageMap = {};
  11906. this.typeMap = {};
  11907. this.packages = [];
  11908. this.properties = properties;
  11909. forEach$1(packages, bind$2(this.registerPackage, this));
  11910. }
  11911. Registry.prototype.getPackage = function(uriOrPrefix) {
  11912. return this.packageMap[uriOrPrefix];
  11913. };
  11914. Registry.prototype.getPackages = function() {
  11915. return this.packages;
  11916. };
  11917. Registry.prototype.registerPackage = function(pkg) {
  11918. // copy package
  11919. pkg = assign$1({}, pkg);
  11920. var pkgMap = this.packageMap;
  11921. ensureAvailable(pkgMap, pkg, 'prefix');
  11922. ensureAvailable(pkgMap, pkg, 'uri');
  11923. // register types
  11924. forEach$1(pkg.types, bind$2(function(descriptor) {
  11925. this.registerType(descriptor, pkg);
  11926. }, this));
  11927. pkgMap[pkg.uri] = pkgMap[pkg.prefix] = pkg;
  11928. this.packages.push(pkg);
  11929. };
  11930. /**
  11931. * Register a type from a specific package with us
  11932. */
  11933. Registry.prototype.registerType = function(type, pkg) {
  11934. type = assign$1({}, type, {
  11935. superClass: (type.superClass || []).slice(),
  11936. extends: (type.extends || []).slice(),
  11937. properties: (type.properties || []).slice(),
  11938. meta: assign$1((type.meta || {}))
  11939. });
  11940. var ns = parseName(type.name, pkg.prefix),
  11941. name = ns.name,
  11942. propertiesByName = {};
  11943. // parse properties
  11944. forEach$1(type.properties, bind$2(function(p) {
  11945. // namespace property names
  11946. var propertyNs = parseName(p.name, ns.prefix),
  11947. propertyName = propertyNs.name;
  11948. // namespace property types
  11949. if (!isBuiltIn(p.type)) {
  11950. p.type = parseName(p.type, propertyNs.prefix).name;
  11951. }
  11952. assign$1(p, {
  11953. ns: propertyNs,
  11954. name: propertyName
  11955. });
  11956. propertiesByName[propertyName] = p;
  11957. }, this));
  11958. // update ns + name
  11959. assign$1(type, {
  11960. ns: ns,
  11961. name: name,
  11962. propertiesByName: propertiesByName
  11963. });
  11964. forEach$1(type.extends, bind$2(function(extendsName) {
  11965. var extendsNameNs = parseName(extendsName, ns.prefix);
  11966. var extended = this.typeMap[extendsNameNs.name];
  11967. extended.traits = extended.traits || [];
  11968. extended.traits.push(name);
  11969. }, this));
  11970. // link to package
  11971. this.definePackage(type, pkg);
  11972. // register
  11973. this.typeMap[name] = type;
  11974. };
  11975. /**
  11976. * Traverse the type hierarchy from bottom to top,
  11977. * calling iterator with (type, inherited) for all elements in
  11978. * the inheritance chain.
  11979. *
  11980. * @param {Object} nsName
  11981. * @param {Function} iterator
  11982. * @param {Boolean} [trait=false]
  11983. */
  11984. Registry.prototype.mapTypes = function(nsName, iterator, trait) {
  11985. var type = isBuiltIn(nsName.name) ? { name: nsName.name } : this.typeMap[nsName.name];
  11986. var self = this;
  11987. /**
  11988. * Traverse the selected super type or trait
  11989. *
  11990. * @param {String} cls
  11991. * @param {Boolean} [trait=false]
  11992. */
  11993. function traverse(cls, trait) {
  11994. var parentNs = parseName(cls, isBuiltIn(cls) ? '' : nsName.prefix);
  11995. self.mapTypes(parentNs, iterator, trait);
  11996. }
  11997. /**
  11998. * Traverse the selected trait.
  11999. *
  12000. * @param {String} cls
  12001. */
  12002. function traverseTrait(cls) {
  12003. return traverse(cls, true);
  12004. }
  12005. /**
  12006. * Traverse the selected super type
  12007. *
  12008. * @param {String} cls
  12009. */
  12010. function traverseSuper(cls) {
  12011. return traverse(cls, false);
  12012. }
  12013. if (!type) {
  12014. throw new Error('unknown type <' + nsName.name + '>');
  12015. }
  12016. forEach$1(type.superClass, trait ? traverseTrait : traverseSuper);
  12017. // call iterator with (type, inherited=!trait)
  12018. iterator(type, !trait);
  12019. forEach$1(type.traits, traverseTrait);
  12020. };
  12021. /**
  12022. * Returns the effective descriptor for a type.
  12023. *
  12024. * @param {String} type the namespaced name (ns:localName) of the type
  12025. *
  12026. * @return {Descriptor} the resulting effective descriptor
  12027. */
  12028. Registry.prototype.getEffectiveDescriptor = function(name) {
  12029. var nsName = parseName(name);
  12030. var builder = new DescriptorBuilder(nsName);
  12031. this.mapTypes(nsName, function(type, inherited) {
  12032. builder.addTrait(type, inherited);
  12033. });
  12034. var descriptor = builder.build();
  12035. // define package link
  12036. this.definePackage(descriptor, descriptor.allTypes[descriptor.allTypes.length - 1].$pkg);
  12037. return descriptor;
  12038. };
  12039. Registry.prototype.definePackage = function(target, pkg) {
  12040. this.properties.define(target, '$pkg', { value: pkg });
  12041. };
  12042. // helpers ////////////////////////////
  12043. function ensureAvailable(packageMap, pkg, identifierKey) {
  12044. var value = pkg[identifierKey];
  12045. if (value in packageMap) {
  12046. throw new Error('package with ' + identifierKey + ' <' + value + '> already defined');
  12047. }
  12048. }
  12049. /**
  12050. * A utility that gets and sets properties of model elements.
  12051. *
  12052. * @param {Model} model
  12053. */
  12054. function Properties(model) {
  12055. this.model = model;
  12056. }
  12057. /**
  12058. * Sets a named property on the target element.
  12059. * If the value is undefined, the property gets deleted.
  12060. *
  12061. * @param {Object} target
  12062. * @param {String} name
  12063. * @param {Object} value
  12064. */
  12065. Properties.prototype.set = function(target, name, value) {
  12066. if (!isString(name) || !name.length) {
  12067. throw new TypeError('property name must be a non-empty string');
  12068. }
  12069. var property = this.getProperty(target, name);
  12070. var propertyName = property && property.name;
  12071. if (isUndefined(value)) {
  12072. // unset the property, if the specified value is undefined;
  12073. // delete from $attrs (for extensions) or the target itself
  12074. if (property) {
  12075. delete target[propertyName];
  12076. } else {
  12077. delete target.$attrs[stripGlobal(name)];
  12078. }
  12079. } else {
  12080. // set the property, defining well defined properties on the fly
  12081. // or simply updating them in target.$attrs (for extensions)
  12082. if (property) {
  12083. if (propertyName in target) {
  12084. target[propertyName] = value;
  12085. } else {
  12086. defineProperty(target, property, value);
  12087. }
  12088. } else {
  12089. target.$attrs[stripGlobal(name)] = value;
  12090. }
  12091. }
  12092. };
  12093. /**
  12094. * Returns the named property of the given element
  12095. *
  12096. * @param {Object} target
  12097. * @param {String} name
  12098. *
  12099. * @return {Object}
  12100. */
  12101. Properties.prototype.get = function(target, name) {
  12102. var property = this.getProperty(target, name);
  12103. if (!property) {
  12104. return target.$attrs[stripGlobal(name)];
  12105. }
  12106. var propertyName = property.name;
  12107. // check if access to collection property and lazily initialize it
  12108. if (!target[propertyName] && property.isMany) {
  12109. defineProperty(target, property, []);
  12110. }
  12111. return target[propertyName];
  12112. };
  12113. /**
  12114. * Define a property on the target element
  12115. *
  12116. * @param {Object} target
  12117. * @param {String} name
  12118. * @param {Object} options
  12119. */
  12120. Properties.prototype.define = function(target, name, options) {
  12121. if (!options.writable) {
  12122. var value = options.value;
  12123. // use getters for read-only variables to support ES6 proxies
  12124. // cf. https://github.com/bpmn-io/internal-docs/issues/386
  12125. options = assign$1({}, options, {
  12126. get: function() { return value; }
  12127. });
  12128. delete options.value;
  12129. }
  12130. Object.defineProperty(target, name, options);
  12131. };
  12132. /**
  12133. * Define the descriptor for an element
  12134. */
  12135. Properties.prototype.defineDescriptor = function(target, descriptor) {
  12136. this.define(target, '$descriptor', { value: descriptor });
  12137. };
  12138. /**
  12139. * Define the model for an element
  12140. */
  12141. Properties.prototype.defineModel = function(target, model) {
  12142. this.define(target, '$model', { value: model });
  12143. };
  12144. /**
  12145. * Return property with the given name on the element.
  12146. *
  12147. * @param {any} target
  12148. * @param {string} name
  12149. *
  12150. * @return {object | null} property
  12151. */
  12152. Properties.prototype.getProperty = function(target, name) {
  12153. var model = this.model;
  12154. var property = model.getPropertyDescriptor(target, name);
  12155. if (property) {
  12156. return property;
  12157. }
  12158. if (name.includes(':')) {
  12159. return null;
  12160. }
  12161. const strict = model.config.strict;
  12162. if (typeof strict !== 'undefined') {
  12163. const error = new TypeError(`unknown property <${ name }> on <${ target.$type }>`);
  12164. if (strict) {
  12165. throw error;
  12166. } else {
  12167. // eslint-disable-next-line no-undef
  12168. typeof console !== 'undefined' && console.warn(error);
  12169. }
  12170. }
  12171. return null;
  12172. };
  12173. function isUndefined(val) {
  12174. return typeof val === 'undefined';
  12175. }
  12176. function defineProperty(target, property, value) {
  12177. Object.defineProperty(target, property.name, {
  12178. enumerable: !property.isReference,
  12179. writable: true,
  12180. value: value,
  12181. configurable: true
  12182. });
  12183. }
  12184. function stripGlobal(name) {
  12185. return name.replace(/^:/, '');
  12186. }
  12187. // Moddle implementation /////////////////////////////////////////////////
  12188. /**
  12189. * @class Moddle
  12190. *
  12191. * A model that can be used to create elements of a specific type.
  12192. *
  12193. * @example
  12194. *
  12195. * var Moddle = require('moddle');
  12196. *
  12197. * var pkg = {
  12198. * name: 'mypackage',
  12199. * prefix: 'my',
  12200. * types: [
  12201. * { name: 'Root' }
  12202. * ]
  12203. * };
  12204. *
  12205. * var moddle = new Moddle([pkg]);
  12206. *
  12207. * @param {Array<Package>} packages the packages to contain
  12208. *
  12209. * @param { { strict?: boolean } } [config] moddle configuration
  12210. */
  12211. function Moddle(packages, config = {}) {
  12212. this.properties = new Properties(this);
  12213. this.factory = new Factory(this, this.properties);
  12214. this.registry = new Registry(packages, this.properties);
  12215. this.typeCache = {};
  12216. this.config = config;
  12217. }
  12218. /**
  12219. * Create an instance of the specified type.
  12220. *
  12221. * @method Moddle#create
  12222. *
  12223. * @example
  12224. *
  12225. * var foo = moddle.create('my:Foo');
  12226. * var bar = moddle.create('my:Bar', { id: 'BAR_1' });
  12227. *
  12228. * @param {String|Object} descriptor the type descriptor or name know to the model
  12229. * @param {Object} attrs a number of attributes to initialize the model instance with
  12230. * @return {Object} model instance
  12231. */
  12232. Moddle.prototype.create = function(descriptor, attrs) {
  12233. var Type = this.getType(descriptor);
  12234. if (!Type) {
  12235. throw new Error('unknown type <' + descriptor + '>');
  12236. }
  12237. return new Type(attrs);
  12238. };
  12239. /**
  12240. * Returns the type representing a given descriptor
  12241. *
  12242. * @method Moddle#getType
  12243. *
  12244. * @example
  12245. *
  12246. * var Foo = moddle.getType('my:Foo');
  12247. * var foo = new Foo({ 'id' : 'FOO_1' });
  12248. *
  12249. * @param {String|Object} descriptor the type descriptor or name know to the model
  12250. * @return {Object} the type representing the descriptor
  12251. */
  12252. Moddle.prototype.getType = function(descriptor) {
  12253. var cache = this.typeCache;
  12254. var name = isString(descriptor) ? descriptor : descriptor.ns.name;
  12255. var type = cache[name];
  12256. if (!type) {
  12257. descriptor = this.registry.getEffectiveDescriptor(name);
  12258. type = cache[name] = this.factory.createType(descriptor);
  12259. }
  12260. return type;
  12261. };
  12262. /**
  12263. * Creates an any-element type to be used within model instances.
  12264. *
  12265. * This can be used to create custom elements that lie outside the meta-model.
  12266. * The created element contains all the meta-data required to serialize it
  12267. * as part of meta-model elements.
  12268. *
  12269. * @method Moddle#createAny
  12270. *
  12271. * @example
  12272. *
  12273. * var foo = moddle.createAny('vendor:Foo', 'http://vendor', {
  12274. * value: 'bar'
  12275. * });
  12276. *
  12277. * var container = moddle.create('my:Container', 'http://my', {
  12278. * any: [ foo ]
  12279. * });
  12280. *
  12281. * // go ahead and serialize the stuff
  12282. *
  12283. *
  12284. * @param {String} name the name of the element
  12285. * @param {String} nsUri the namespace uri of the element
  12286. * @param {Object} [properties] a map of properties to initialize the instance with
  12287. * @return {Object} the any type instance
  12288. */
  12289. Moddle.prototype.createAny = function(name, nsUri, properties) {
  12290. var nameNs = parseName(name);
  12291. var element = {
  12292. $type: name,
  12293. $instanceOf: function(type) {
  12294. return type === this.$type;
  12295. },
  12296. get: function(key) {
  12297. return this[key];
  12298. },
  12299. set: function(key, value) {
  12300. set$1(this, [ key ], value);
  12301. }
  12302. };
  12303. var descriptor = {
  12304. name: name,
  12305. isGeneric: true,
  12306. ns: {
  12307. prefix: nameNs.prefix,
  12308. localName: nameNs.localName,
  12309. uri: nsUri
  12310. }
  12311. };
  12312. this.properties.defineDescriptor(element, descriptor);
  12313. this.properties.defineModel(element, this);
  12314. this.properties.define(element, 'get', { enumerable: false, writable: true });
  12315. this.properties.define(element, 'set', { enumerable: false, writable: true });
  12316. this.properties.define(element, '$parent', { enumerable: false, writable: true });
  12317. this.properties.define(element, '$instanceOf', { enumerable: false, writable: true });
  12318. forEach$1(properties, function(a, key) {
  12319. if (isObject(a) && a.value !== undefined) {
  12320. element[a.name] = a.value;
  12321. } else {
  12322. element[key] = a;
  12323. }
  12324. });
  12325. return element;
  12326. };
  12327. /**
  12328. * Returns a registered package by uri or prefix
  12329. *
  12330. * @return {Object} the package
  12331. */
  12332. Moddle.prototype.getPackage = function(uriOrPrefix) {
  12333. return this.registry.getPackage(uriOrPrefix);
  12334. };
  12335. /**
  12336. * Returns a snapshot of all known packages
  12337. *
  12338. * @return {Object} the package
  12339. */
  12340. Moddle.prototype.getPackages = function() {
  12341. return this.registry.getPackages();
  12342. };
  12343. /**
  12344. * Returns the descriptor for an element
  12345. */
  12346. Moddle.prototype.getElementDescriptor = function(element) {
  12347. return element.$descriptor;
  12348. };
  12349. /**
  12350. * Returns true if the given descriptor or instance
  12351. * represents the given type.
  12352. *
  12353. * May be applied to this, if element is omitted.
  12354. */
  12355. Moddle.prototype.hasType = function(element, type) {
  12356. if (type === undefined) {
  12357. type = element;
  12358. element = this;
  12359. }
  12360. var descriptor = element.$model.getElementDescriptor(element);
  12361. return (type in descriptor.allTypesByName);
  12362. };
  12363. /**
  12364. * Returns the descriptor of an elements named property
  12365. */
  12366. Moddle.prototype.getPropertyDescriptor = function(element, property) {
  12367. return this.getElementDescriptor(element).propertiesByName[property];
  12368. };
  12369. /**
  12370. * Returns a mapped type's descriptor
  12371. */
  12372. Moddle.prototype.getTypeDescriptor = function(type) {
  12373. return this.registry.typeMap[type];
  12374. };
  12375. var fromCharCode = String.fromCharCode;
  12376. var hasOwnProperty = Object.prototype.hasOwnProperty;
  12377. var ENTITY_PATTERN = /&#(\d+);|&#x([0-9a-f]+);|&(\w+);/ig;
  12378. var ENTITY_MAPPING = {
  12379. 'amp': '&',
  12380. 'apos': '\'',
  12381. 'gt': '>',
  12382. 'lt': '<',
  12383. 'quot': '"'
  12384. };
  12385. // map UPPERCASE variants of supported special chars
  12386. Object.keys(ENTITY_MAPPING).forEach(function(k) {
  12387. ENTITY_MAPPING[k.toUpperCase()] = ENTITY_MAPPING[k];
  12388. });
  12389. function replaceEntities(_, d, x, z) {
  12390. // reserved names, i.e. &nbsp;
  12391. if (z) {
  12392. if (hasOwnProperty.call(ENTITY_MAPPING, z)) {
  12393. return ENTITY_MAPPING[z];
  12394. } else {
  12395. // fall back to original value
  12396. return '&' + z + ';';
  12397. }
  12398. }
  12399. // decimal encoded char
  12400. if (d) {
  12401. return fromCharCode(d);
  12402. }
  12403. // hex encoded char
  12404. return fromCharCode(parseInt(x, 16));
  12405. }
  12406. /**
  12407. * A basic entity decoder that can decode a minimal
  12408. * sub-set of reserved names (&amp;) as well as
  12409. * hex (&#xaaf;) and decimal (&#1231;) encoded characters.
  12410. *
  12411. * @param {string} str
  12412. *
  12413. * @return {string} decoded string
  12414. */
  12415. function decodeEntities(s) {
  12416. if (s.length > 3 && s.indexOf('&') !== -1) {
  12417. return s.replace(ENTITY_PATTERN, replaceEntities);
  12418. }
  12419. return s;
  12420. }
  12421. var XSI_URI = 'http://www.w3.org/2001/XMLSchema-instance';
  12422. var XSI_PREFIX = 'xsi';
  12423. var XSI_TYPE$1 = 'xsi:type';
  12424. var NON_WHITESPACE_OUTSIDE_ROOT_NODE = 'non-whitespace outside of root node';
  12425. function error$1(msg) {
  12426. return new Error(msg);
  12427. }
  12428. function missingNamespaceForPrefix(prefix) {
  12429. return 'missing namespace for prefix <' + prefix + '>';
  12430. }
  12431. function getter(getFn) {
  12432. return {
  12433. 'get': getFn,
  12434. 'enumerable': true
  12435. };
  12436. }
  12437. function cloneNsMatrix(nsMatrix) {
  12438. var clone = {}, key;
  12439. for (key in nsMatrix) {
  12440. clone[key] = nsMatrix[key];
  12441. }
  12442. return clone;
  12443. }
  12444. function uriPrefix(prefix) {
  12445. return prefix + '$uri';
  12446. }
  12447. function buildNsMatrix(nsUriToPrefix) {
  12448. var nsMatrix = {},
  12449. uri,
  12450. prefix;
  12451. for (uri in nsUriToPrefix) {
  12452. prefix = nsUriToPrefix[uri];
  12453. nsMatrix[prefix] = prefix;
  12454. nsMatrix[uriPrefix(prefix)] = uri;
  12455. }
  12456. return nsMatrix;
  12457. }
  12458. function noopGetContext() {
  12459. return { 'line': 0, 'column': 0 };
  12460. }
  12461. function throwFunc(err) {
  12462. throw err;
  12463. }
  12464. /**
  12465. * Creates a new parser with the given options.
  12466. *
  12467. * @constructor
  12468. *
  12469. * @param {!Object<string, ?>=} options
  12470. */
  12471. function Parser(options) {
  12472. if (!this) {
  12473. return new Parser(options);
  12474. }
  12475. var proxy = options && options['proxy'];
  12476. var onText,
  12477. onOpenTag,
  12478. onCloseTag,
  12479. onCDATA,
  12480. onError = throwFunc,
  12481. onWarning,
  12482. onComment,
  12483. onQuestion,
  12484. onAttention;
  12485. var getContext = noopGetContext;
  12486. /**
  12487. * Do we need to parse the current elements attributes for namespaces?
  12488. *
  12489. * @type {boolean}
  12490. */
  12491. var maybeNS = false;
  12492. /**
  12493. * Do we process namespaces at all?
  12494. *
  12495. * @type {boolean}
  12496. */
  12497. var isNamespace = false;
  12498. /**
  12499. * The caught error returned on parse end
  12500. *
  12501. * @type {Error}
  12502. */
  12503. var returnError = null;
  12504. /**
  12505. * Should we stop parsing?
  12506. *
  12507. * @type {boolean}
  12508. */
  12509. var parseStop = false;
  12510. /**
  12511. * A map of { uri: prefix } used by the parser.
  12512. *
  12513. * This map will ensure we can normalize prefixes during processing;
  12514. * for each uri, only one prefix will be exposed to the handlers.
  12515. *
  12516. * @type {!Object<string, string>}}
  12517. */
  12518. var nsUriToPrefix;
  12519. /**
  12520. * Handle parse error.
  12521. *
  12522. * @param {string|Error} err
  12523. */
  12524. function handleError(err) {
  12525. if (!(err instanceof Error)) {
  12526. err = error$1(err);
  12527. }
  12528. returnError = err;
  12529. onError(err, getContext);
  12530. }
  12531. /**
  12532. * Handle parse error.
  12533. *
  12534. * @param {string|Error} err
  12535. */
  12536. function handleWarning(err) {
  12537. if (!onWarning) {
  12538. return;
  12539. }
  12540. if (!(err instanceof Error)) {
  12541. err = error$1(err);
  12542. }
  12543. onWarning(err, getContext);
  12544. }
  12545. /**
  12546. * Register parse listener.
  12547. *
  12548. * @param {string} name
  12549. * @param {Function} cb
  12550. *
  12551. * @return {Parser}
  12552. */
  12553. this['on'] = function(name, cb) {
  12554. if (typeof cb !== 'function') {
  12555. throw error$1('required args <name, cb>');
  12556. }
  12557. switch (name) {
  12558. case 'openTag': onOpenTag = cb; break;
  12559. case 'text': onText = cb; break;
  12560. case 'closeTag': onCloseTag = cb; break;
  12561. case 'error': onError = cb; break;
  12562. case 'warn': onWarning = cb; break;
  12563. case 'cdata': onCDATA = cb; break;
  12564. case 'attention': onAttention = cb; break; // <!XXXXX zzzz="eeee">
  12565. case 'question': onQuestion = cb; break; // <? .... ?>
  12566. case 'comment': onComment = cb; break;
  12567. default:
  12568. throw error$1('unsupported event: ' + name);
  12569. }
  12570. return this;
  12571. };
  12572. /**
  12573. * Set the namespace to prefix mapping.
  12574. *
  12575. * @example
  12576. *
  12577. * parser.ns({
  12578. * 'http://foo': 'foo',
  12579. * 'http://bar': 'bar'
  12580. * });
  12581. *
  12582. * @param {!Object<string, string>} nsMap
  12583. *
  12584. * @return {Parser}
  12585. */
  12586. this['ns'] = function(nsMap) {
  12587. if (typeof nsMap === 'undefined') {
  12588. nsMap = {};
  12589. }
  12590. if (typeof nsMap !== 'object') {
  12591. throw error$1('required args <nsMap={}>');
  12592. }
  12593. var _nsUriToPrefix = {}, k;
  12594. for (k in nsMap) {
  12595. _nsUriToPrefix[k] = nsMap[k];
  12596. }
  12597. // FORCE default mapping for schema instance
  12598. _nsUriToPrefix[XSI_URI] = XSI_PREFIX;
  12599. isNamespace = true;
  12600. nsUriToPrefix = _nsUriToPrefix;
  12601. return this;
  12602. };
  12603. /**
  12604. * Parse xml string.
  12605. *
  12606. * @param {string} xml
  12607. *
  12608. * @return {Error} returnError, if not thrown
  12609. */
  12610. this['parse'] = function(xml) {
  12611. if (typeof xml !== 'string') {
  12612. throw error$1('required args <xml=string>');
  12613. }
  12614. returnError = null;
  12615. parse(xml);
  12616. getContext = noopGetContext;
  12617. parseStop = false;
  12618. return returnError;
  12619. };
  12620. /**
  12621. * Stop parsing.
  12622. */
  12623. this['stop'] = function() {
  12624. parseStop = true;
  12625. };
  12626. /**
  12627. * Parse string, invoking configured listeners on element.
  12628. *
  12629. * @param {string} xml
  12630. */
  12631. function parse(xml) {
  12632. var nsMatrixStack = isNamespace ? [] : null,
  12633. nsMatrix = isNamespace ? buildNsMatrix(nsUriToPrefix) : null,
  12634. _nsMatrix,
  12635. nodeStack = [],
  12636. anonymousNsCount = 0,
  12637. tagStart = false,
  12638. tagEnd = false,
  12639. i = 0, j = 0,
  12640. x, y, q, w, v,
  12641. xmlns,
  12642. elementName,
  12643. _elementName,
  12644. elementProxy
  12645. ;
  12646. var attrsString = '',
  12647. attrsStart = 0,
  12648. cachedAttrs // false = parsed with errors, null = needs parsing
  12649. ;
  12650. /**
  12651. * Parse attributes on demand and returns the parsed attributes.
  12652. *
  12653. * Return semantics: (1) `false` on attribute parse error,
  12654. * (2) object hash on extracted attrs.
  12655. *
  12656. * @return {boolean|Object}
  12657. */
  12658. function getAttrs() {
  12659. if (cachedAttrs !== null) {
  12660. return cachedAttrs;
  12661. }
  12662. var nsUri,
  12663. nsUriPrefix,
  12664. nsName,
  12665. defaultAlias = isNamespace && nsMatrix['xmlns'],
  12666. attrList = isNamespace && maybeNS ? [] : null,
  12667. i = attrsStart,
  12668. s = attrsString,
  12669. l = s.length,
  12670. hasNewMatrix,
  12671. newalias,
  12672. value,
  12673. alias,
  12674. name,
  12675. attrs = {},
  12676. seenAttrs = {},
  12677. skipAttr,
  12678. w,
  12679. j;
  12680. parseAttr:
  12681. for (; i < l; i++) {
  12682. skipAttr = false;
  12683. w = s.charCodeAt(i);
  12684. if (w === 32 || (w < 14 && w > 8)) { // WHITESPACE={ \f\n\r\t\v}
  12685. continue;
  12686. }
  12687. // wait for non whitespace character
  12688. if (w < 65 || w > 122 || (w > 90 && w < 97)) {
  12689. if (w !== 95 && w !== 58) { // char 95"_" 58":"
  12690. handleWarning('illegal first char attribute name');
  12691. skipAttr = true;
  12692. }
  12693. }
  12694. // parse attribute name
  12695. for (j = i + 1; j < l; j++) {
  12696. w = s.charCodeAt(j);
  12697. if (
  12698. w > 96 && w < 123 ||
  12699. w > 64 && w < 91 ||
  12700. w > 47 && w < 59 ||
  12701. w === 46 || // '.'
  12702. w === 45 || // '-'
  12703. w === 95 // '_'
  12704. ) {
  12705. continue;
  12706. }
  12707. // unexpected whitespace
  12708. if (w === 32 || (w < 14 && w > 8)) { // WHITESPACE
  12709. handleWarning('missing attribute value');
  12710. i = j;
  12711. continue parseAttr;
  12712. }
  12713. // expected "="
  12714. if (w === 61) { // "=" == 61
  12715. break;
  12716. }
  12717. handleWarning('illegal attribute name char');
  12718. skipAttr = true;
  12719. }
  12720. name = s.substring(i, j);
  12721. if (name === 'xmlns:xmlns') {
  12722. handleWarning('illegal declaration of xmlns');
  12723. skipAttr = true;
  12724. }
  12725. w = s.charCodeAt(j + 1);
  12726. if (w === 34) { // '"'
  12727. j = s.indexOf('"', i = j + 2);
  12728. if (j === -1) {
  12729. j = s.indexOf('\'', i);
  12730. if (j !== -1) {
  12731. handleWarning('attribute value quote missmatch');
  12732. skipAttr = true;
  12733. }
  12734. }
  12735. } else if (w === 39) { // "'"
  12736. j = s.indexOf('\'', i = j + 2);
  12737. if (j === -1) {
  12738. j = s.indexOf('"', i);
  12739. if (j !== -1) {
  12740. handleWarning('attribute value quote missmatch');
  12741. skipAttr = true;
  12742. }
  12743. }
  12744. } else {
  12745. handleWarning('missing attribute value quotes');
  12746. skipAttr = true;
  12747. // skip to next space
  12748. for (j = j + 1; j < l; j++) {
  12749. w = s.charCodeAt(j + 1);
  12750. if (w === 32 || (w < 14 && w > 8)) { // WHITESPACE
  12751. break;
  12752. }
  12753. }
  12754. }
  12755. if (j === -1) {
  12756. handleWarning('missing closing quotes');
  12757. j = l;
  12758. skipAttr = true;
  12759. }
  12760. if (!skipAttr) {
  12761. value = s.substring(i, j);
  12762. }
  12763. i = j;
  12764. // ensure SPACE follows attribute
  12765. // skip illegal content otherwise
  12766. // example a="b"c
  12767. for (; j + 1 < l; j++) {
  12768. w = s.charCodeAt(j + 1);
  12769. if (w === 32 || (w < 14 && w > 8)) { // WHITESPACE
  12770. break;
  12771. }
  12772. // FIRST ILLEGAL CHAR
  12773. if (i === j) {
  12774. handleWarning('illegal character after attribute end');
  12775. skipAttr = true;
  12776. }
  12777. }
  12778. // advance cursor to next attribute
  12779. i = j + 1;
  12780. if (skipAttr) {
  12781. continue parseAttr;
  12782. }
  12783. // check attribute re-declaration
  12784. if (name in seenAttrs) {
  12785. handleWarning('attribute <' + name + '> already defined');
  12786. continue;
  12787. }
  12788. seenAttrs[name] = true;
  12789. if (!isNamespace) {
  12790. attrs[name] = value;
  12791. continue;
  12792. }
  12793. // try to extract namespace information
  12794. if (maybeNS) {
  12795. newalias = (
  12796. name === 'xmlns'
  12797. ? 'xmlns'
  12798. : (name.charCodeAt(0) === 120 && name.substr(0, 6) === 'xmlns:')
  12799. ? name.substr(6)
  12800. : null
  12801. );
  12802. // handle xmlns(:alias) assignment
  12803. if (newalias !== null) {
  12804. nsUri = decodeEntities(value);
  12805. nsUriPrefix = uriPrefix(newalias);
  12806. alias = nsUriToPrefix[nsUri];
  12807. if (!alias) {
  12808. // no prefix defined or prefix collision
  12809. if (
  12810. (newalias === 'xmlns') ||
  12811. (nsUriPrefix in nsMatrix && nsMatrix[nsUriPrefix] !== nsUri)
  12812. ) {
  12813. // alocate free ns prefix
  12814. do {
  12815. alias = 'ns' + (anonymousNsCount++);
  12816. } while (typeof nsMatrix[alias] !== 'undefined');
  12817. } else {
  12818. alias = newalias;
  12819. }
  12820. nsUriToPrefix[nsUri] = alias;
  12821. }
  12822. if (nsMatrix[newalias] !== alias) {
  12823. if (!hasNewMatrix) {
  12824. nsMatrix = cloneNsMatrix(nsMatrix);
  12825. hasNewMatrix = true;
  12826. }
  12827. nsMatrix[newalias] = alias;
  12828. if (newalias === 'xmlns') {
  12829. nsMatrix[uriPrefix(alias)] = nsUri;
  12830. defaultAlias = alias;
  12831. }
  12832. nsMatrix[nsUriPrefix] = nsUri;
  12833. }
  12834. // expose xmlns(:asd)="..." in attributes
  12835. attrs[name] = value;
  12836. continue;
  12837. }
  12838. // collect attributes until all namespace
  12839. // declarations are processed
  12840. attrList.push(name, value);
  12841. continue;
  12842. } /** end if (maybeNs) */
  12843. // handle attributes on element without
  12844. // namespace declarations
  12845. w = name.indexOf(':');
  12846. if (w === -1) {
  12847. attrs[name] = value;
  12848. continue;
  12849. }
  12850. // normalize ns attribute name
  12851. if (!(nsName = nsMatrix[name.substring(0, w)])) {
  12852. handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
  12853. continue;
  12854. }
  12855. name = defaultAlias === nsName
  12856. ? name.substr(w + 1)
  12857. : nsName + name.substr(w);
  12858. // end: normalize ns attribute name
  12859. // normalize xsi:type ns attribute value
  12860. if (name === XSI_TYPE$1) {
  12861. w = value.indexOf(':');
  12862. if (w !== -1) {
  12863. nsName = value.substring(0, w);
  12864. // handle default prefixes, i.e. xs:String gracefully
  12865. nsName = nsMatrix[nsName] || nsName;
  12866. value = nsName + value.substring(w);
  12867. } else {
  12868. value = defaultAlias + ':' + value;
  12869. }
  12870. }
  12871. // end: normalize xsi:type ns attribute value
  12872. attrs[name] = value;
  12873. }
  12874. // handle deferred, possibly namespaced attributes
  12875. if (maybeNS) {
  12876. // normalize captured attributes
  12877. for (i = 0, l = attrList.length; i < l; i++) {
  12878. name = attrList[i++];
  12879. value = attrList[i];
  12880. w = name.indexOf(':');
  12881. if (w !== -1) {
  12882. // normalize ns attribute name
  12883. if (!(nsName = nsMatrix[name.substring(0, w)])) {
  12884. handleWarning(missingNamespaceForPrefix(name.substring(0, w)));
  12885. continue;
  12886. }
  12887. name = defaultAlias === nsName
  12888. ? name.substr(w + 1)
  12889. : nsName + name.substr(w);
  12890. // end: normalize ns attribute name
  12891. // normalize xsi:type ns attribute value
  12892. if (name === XSI_TYPE$1) {
  12893. w = value.indexOf(':');
  12894. if (w !== -1) {
  12895. nsName = value.substring(0, w);
  12896. // handle default prefixes, i.e. xs:String gracefully
  12897. nsName = nsMatrix[nsName] || nsName;
  12898. value = nsName + value.substring(w);
  12899. } else {
  12900. value = defaultAlias + ':' + value;
  12901. }
  12902. }
  12903. // end: normalize xsi:type ns attribute value
  12904. }
  12905. attrs[name] = value;
  12906. }
  12907. // end: normalize captured attributes
  12908. }
  12909. return cachedAttrs = attrs;
  12910. }
  12911. /**
  12912. * Extract the parse context { line, column, part }
  12913. * from the current parser position.
  12914. *
  12915. * @return {Object} parse context
  12916. */
  12917. function getParseContext() {
  12918. var splitsRe = /(\r\n|\r|\n)/g;
  12919. var line = 0;
  12920. var column = 0;
  12921. var startOfLine = 0;
  12922. var endOfLine = j;
  12923. var match;
  12924. var data;
  12925. while (i >= startOfLine) {
  12926. match = splitsRe.exec(xml);
  12927. if (!match) {
  12928. break;
  12929. }
  12930. // end of line = (break idx + break chars)
  12931. endOfLine = match[0].length + match.index;
  12932. if (endOfLine > i) {
  12933. break;
  12934. }
  12935. // advance to next line
  12936. line += 1;
  12937. startOfLine = endOfLine;
  12938. }
  12939. // EOF errors
  12940. if (i == -1) {
  12941. column = endOfLine;
  12942. data = xml.substring(j);
  12943. } else
  12944. // start errors
  12945. if (j === 0) {
  12946. data = xml.substring(j, i);
  12947. }
  12948. // other errors
  12949. else {
  12950. column = i - startOfLine;
  12951. data = (j == -1 ? xml.substring(i) : xml.substring(i, j + 1));
  12952. }
  12953. return {
  12954. 'data': data,
  12955. 'line': line,
  12956. 'column': column
  12957. };
  12958. }
  12959. getContext = getParseContext;
  12960. if (proxy) {
  12961. elementProxy = Object.create({}, {
  12962. 'name': getter(function() {
  12963. return elementName;
  12964. }),
  12965. 'originalName': getter(function() {
  12966. return _elementName;
  12967. }),
  12968. 'attrs': getter(getAttrs),
  12969. 'ns': getter(function() {
  12970. return nsMatrix;
  12971. })
  12972. });
  12973. }
  12974. // actual parse logic
  12975. while (j !== -1) {
  12976. if (xml.charCodeAt(j) === 60) { // "<"
  12977. i = j;
  12978. } else {
  12979. i = xml.indexOf('<', j);
  12980. }
  12981. // parse end
  12982. if (i === -1) {
  12983. if (nodeStack.length) {
  12984. return handleError('unexpected end of file');
  12985. }
  12986. if (j === 0) {
  12987. return handleError('missing start tag');
  12988. }
  12989. if (j < xml.length) {
  12990. if (xml.substring(j).trim()) {
  12991. handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
  12992. }
  12993. }
  12994. return;
  12995. }
  12996. // parse text
  12997. if (j !== i) {
  12998. if (nodeStack.length) {
  12999. if (onText) {
  13000. onText(xml.substring(j, i), decodeEntities, getContext);
  13001. if (parseStop) {
  13002. return;
  13003. }
  13004. }
  13005. } else {
  13006. if (xml.substring(j, i).trim()) {
  13007. handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE);
  13008. if (parseStop) {
  13009. return;
  13010. }
  13011. }
  13012. }
  13013. }
  13014. w = xml.charCodeAt(i+1);
  13015. // parse comments + CDATA
  13016. if (w === 33) { // "!"
  13017. q = xml.charCodeAt(i+2);
  13018. // CDATA section
  13019. if (q === 91 && xml.substr(i + 3, 6) === 'CDATA[') { // 91 == "["
  13020. j = xml.indexOf(']]>', i);
  13021. if (j === -1) {
  13022. return handleError('unclosed cdata');
  13023. }
  13024. if (onCDATA) {
  13025. onCDATA(xml.substring(i + 9, j), getContext);
  13026. if (parseStop) {
  13027. return;
  13028. }
  13029. }
  13030. j += 3;
  13031. continue;
  13032. }
  13033. // comment
  13034. if (q === 45 && xml.charCodeAt(i + 3) === 45) { // 45 == "-"
  13035. j = xml.indexOf('-->', i);
  13036. if (j === -1) {
  13037. return handleError('unclosed comment');
  13038. }
  13039. if (onComment) {
  13040. onComment(xml.substring(i + 4, j), decodeEntities, getContext);
  13041. if (parseStop) {
  13042. return;
  13043. }
  13044. }
  13045. j += 3;
  13046. continue;
  13047. }
  13048. }
  13049. // parse question <? ... ?>
  13050. if (w === 63) { // "?"
  13051. j = xml.indexOf('?>', i);
  13052. if (j === -1) {
  13053. return handleError('unclosed question');
  13054. }
  13055. if (onQuestion) {
  13056. onQuestion(xml.substring(i, j + 2), getContext);
  13057. if (parseStop) {
  13058. return;
  13059. }
  13060. }
  13061. j += 2;
  13062. continue;
  13063. }
  13064. // find matching closing tag for attention or standard tags
  13065. // for that we must skip through attribute values
  13066. // (enclosed in single or double quotes)
  13067. for (x = i + 1; ; x++) {
  13068. v = xml.charCodeAt(x);
  13069. if (isNaN(v)) {
  13070. j = -1;
  13071. return handleError('unclosed tag');
  13072. }
  13073. // [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
  13074. // skips the quoted string
  13075. // (double quotes) does not appear in a literal enclosed by (double quotes)
  13076. // (single quote) does not appear in a literal enclosed by (single quote)
  13077. if (v === 34) { // '"'
  13078. q = xml.indexOf('"', x + 1);
  13079. x = q !== -1 ? q : x;
  13080. } else if (v === 39) { // "'"
  13081. q = xml.indexOf("'", x + 1);
  13082. x = q !== -1 ? q : x;
  13083. } else if (v === 62) { // '>'
  13084. j = x;
  13085. break;
  13086. }
  13087. }
  13088. // parse attention <! ...>
  13089. // previously comment and CDATA have already been parsed
  13090. if (w === 33) { // "!"
  13091. if (onAttention) {
  13092. onAttention(xml.substring(i, j + 1), decodeEntities, getContext);
  13093. if (parseStop) {
  13094. return;
  13095. }
  13096. }
  13097. j += 1;
  13098. continue;
  13099. }
  13100. // don't process attributes;
  13101. // there are none
  13102. cachedAttrs = {};
  13103. // if (xml.charCodeAt(i+1) === 47) { // </...
  13104. if (w === 47) { // </...
  13105. tagStart = false;
  13106. tagEnd = true;
  13107. if (!nodeStack.length) {
  13108. return handleError('missing open tag');
  13109. }
  13110. // verify open <-> close tag match
  13111. x = elementName = nodeStack.pop();
  13112. q = i + 2 + x.length;
  13113. if (xml.substring(i + 2, q) !== x) {
  13114. return handleError('closing tag mismatch');
  13115. }
  13116. // verify chars in close tag
  13117. for (; q < j; q++) {
  13118. w = xml.charCodeAt(q);
  13119. if (w === 32 || (w > 8 && w < 14)) { // \f\n\r\t\v space
  13120. continue;
  13121. }
  13122. return handleError('close tag');
  13123. }
  13124. } else {
  13125. if (xml.charCodeAt(j - 1) === 47) { // .../>
  13126. x = elementName = xml.substring(i + 1, j - 1);
  13127. tagStart = true;
  13128. tagEnd = true;
  13129. } else {
  13130. x = elementName = xml.substring(i + 1, j);
  13131. tagStart = true;
  13132. tagEnd = false;
  13133. }
  13134. if (!(w > 96 && w < 123 || w > 64 && w < 91 || w === 95 || w === 58)) { // char 95"_" 58":"
  13135. return handleError('illegal first char nodeName');
  13136. }
  13137. for (q = 1, y = x.length; q < y; q++) {
  13138. w = x.charCodeAt(q);
  13139. if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 95 || w == 46) {
  13140. continue;
  13141. }
  13142. if (w === 32 || (w < 14 && w > 8)) { // \f\n\r\t\v space
  13143. elementName = x.substring(0, q);
  13144. // maybe there are attributes
  13145. cachedAttrs = null;
  13146. break;
  13147. }
  13148. return handleError('invalid nodeName');
  13149. }
  13150. if (!tagEnd) {
  13151. nodeStack.push(elementName);
  13152. }
  13153. }
  13154. if (isNamespace) {
  13155. _nsMatrix = nsMatrix;
  13156. if (tagStart) {
  13157. // remember old namespace
  13158. // unless we're self-closing
  13159. if (!tagEnd) {
  13160. nsMatrixStack.push(_nsMatrix);
  13161. }
  13162. if (cachedAttrs === null) {
  13163. // quick check, whether there may be namespace
  13164. // declarations on the node; if that is the case
  13165. // we need to eagerly parse the node attributes
  13166. if ((maybeNS = x.indexOf('xmlns', q) !== -1)) {
  13167. attrsStart = q;
  13168. attrsString = x;
  13169. getAttrs();
  13170. maybeNS = false;
  13171. }
  13172. }
  13173. }
  13174. _elementName = elementName;
  13175. w = elementName.indexOf(':');
  13176. if (w !== -1) {
  13177. xmlns = nsMatrix[elementName.substring(0, w)];
  13178. // prefix given; namespace must exist
  13179. if (!xmlns) {
  13180. return handleError('missing namespace on <' + _elementName + '>');
  13181. }
  13182. elementName = elementName.substr(w + 1);
  13183. } else {
  13184. xmlns = nsMatrix['xmlns'];
  13185. // if no default namespace is defined,
  13186. // we'll import the element as anonymous.
  13187. //
  13188. // it is up to users to correct that to the document defined
  13189. // targetNamespace, or whatever their undersanding of the
  13190. // XML spec mandates.
  13191. }
  13192. // adjust namespace prefixs as configured
  13193. if (xmlns) {
  13194. elementName = xmlns + ':' + elementName;
  13195. }
  13196. }
  13197. if (tagStart) {
  13198. attrsStart = q;
  13199. attrsString = x;
  13200. if (onOpenTag) {
  13201. if (proxy) {
  13202. onOpenTag(elementProxy, decodeEntities, tagEnd, getContext);
  13203. } else {
  13204. onOpenTag(elementName, getAttrs, decodeEntities, tagEnd, getContext);
  13205. }
  13206. if (parseStop) {
  13207. return;
  13208. }
  13209. }
  13210. }
  13211. if (tagEnd) {
  13212. if (onCloseTag) {
  13213. onCloseTag(proxy ? elementProxy : elementName, decodeEntities, tagStart, getContext);
  13214. if (parseStop) {
  13215. return;
  13216. }
  13217. }
  13218. // restore old namespace
  13219. if (isNamespace) {
  13220. if (!tagStart) {
  13221. nsMatrix = nsMatrixStack.pop();
  13222. } else {
  13223. nsMatrix = _nsMatrix;
  13224. }
  13225. }
  13226. }
  13227. j += 1;
  13228. }
  13229. } /** end parse */
  13230. }
  13231. function hasLowerCaseAlias(pkg) {
  13232. return pkg.xml && pkg.xml.tagAlias === 'lowerCase';
  13233. }
  13234. var DEFAULT_NS_MAP = {
  13235. 'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
  13236. 'xml': 'http://www.w3.org/XML/1998/namespace'
  13237. };
  13238. var XSI_TYPE = 'xsi:type';
  13239. function serializeFormat(element) {
  13240. return element.xml && element.xml.serialize;
  13241. }
  13242. function serializeAsType(element) {
  13243. return serializeFormat(element) === XSI_TYPE;
  13244. }
  13245. function serializeAsProperty(element) {
  13246. return serializeFormat(element) === 'property';
  13247. }
  13248. function capitalize(str) {
  13249. return str.charAt(0).toUpperCase() + str.slice(1);
  13250. }
  13251. function aliasToName(aliasNs, pkg) {
  13252. if (!hasLowerCaseAlias(pkg)) {
  13253. return aliasNs.name;
  13254. }
  13255. return aliasNs.prefix + ':' + capitalize(aliasNs.localName);
  13256. }
  13257. function prefixedToName(nameNs, pkg) {
  13258. var name = nameNs.name,
  13259. localName = nameNs.localName;
  13260. var typePrefix = pkg.xml && pkg.xml.typePrefix;
  13261. if (typePrefix && localName.indexOf(typePrefix) === 0) {
  13262. return nameNs.prefix + ':' + localName.slice(typePrefix.length);
  13263. } else {
  13264. return name;
  13265. }
  13266. }
  13267. function normalizeXsiTypeName(name, model) {
  13268. var nameNs = parseName(name);
  13269. var pkg = model.getPackage(nameNs.prefix);
  13270. return prefixedToName(nameNs, pkg);
  13271. }
  13272. function error(message) {
  13273. return new Error(message);
  13274. }
  13275. /**
  13276. * Get the moddle descriptor for a given instance or type.
  13277. *
  13278. * @param {ModdleElement|Function} element
  13279. *
  13280. * @return {Object} the moddle descriptor
  13281. */
  13282. function getModdleDescriptor(element) {
  13283. return element.$descriptor;
  13284. }
  13285. /**
  13286. * A parse context.
  13287. *
  13288. * @class
  13289. *
  13290. * @param {Object} options
  13291. * @param {ElementHandler} options.rootHandler the root handler for parsing a document
  13292. * @param {boolean} [options.lax=false] whether or not to ignore invalid elements
  13293. */
  13294. function Context(options) {
  13295. /**
  13296. * @property {ElementHandler} rootHandler
  13297. */
  13298. /**
  13299. * @property {Boolean} lax
  13300. */
  13301. assign$1(this, options);
  13302. this.elementsById = {};
  13303. this.references = [];
  13304. this.warnings = [];
  13305. /**
  13306. * Add an unresolved reference.
  13307. *
  13308. * @param {Object} reference
  13309. */
  13310. this.addReference = function(reference) {
  13311. this.references.push(reference);
  13312. };
  13313. /**
  13314. * Add a processed element.
  13315. *
  13316. * @param {ModdleElement} element
  13317. */
  13318. this.addElement = function(element) {
  13319. if (!element) {
  13320. throw error('expected element');
  13321. }
  13322. var elementsById = this.elementsById;
  13323. var descriptor = getModdleDescriptor(element);
  13324. var idProperty = descriptor.idProperty,
  13325. id;
  13326. if (idProperty) {
  13327. id = element.get(idProperty.name);
  13328. if (id) {
  13329. // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
  13330. if (!/^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i.test(id)) {
  13331. throw new Error('illegal ID <' + id + '>');
  13332. }
  13333. if (elementsById[id]) {
  13334. throw error('duplicate ID <' + id + '>');
  13335. }
  13336. elementsById[id] = element;
  13337. }
  13338. }
  13339. };
  13340. /**
  13341. * Add an import warning.
  13342. *
  13343. * @param {Object} warning
  13344. * @param {String} warning.message
  13345. * @param {Error} [warning.error]
  13346. */
  13347. this.addWarning = function(warning) {
  13348. this.warnings.push(warning);
  13349. };
  13350. }
  13351. function BaseHandler() {}
  13352. BaseHandler.prototype.handleEnd = function() {};
  13353. BaseHandler.prototype.handleText = function() {};
  13354. BaseHandler.prototype.handleNode = function() {};
  13355. /**
  13356. * A simple pass through handler that does nothing except for
  13357. * ignoring all input it receives.
  13358. *
  13359. * This is used to ignore unknown elements and
  13360. * attributes.
  13361. */
  13362. function NoopHandler() { }
  13363. NoopHandler.prototype = Object.create(BaseHandler.prototype);
  13364. NoopHandler.prototype.handleNode = function() {
  13365. return this;
  13366. };
  13367. function BodyHandler() {}
  13368. BodyHandler.prototype = Object.create(BaseHandler.prototype);
  13369. BodyHandler.prototype.handleText = function(text) {
  13370. this.body = (this.body || '') + text;
  13371. };
  13372. function ReferenceHandler(property, context) {
  13373. this.property = property;
  13374. this.context = context;
  13375. }
  13376. ReferenceHandler.prototype = Object.create(BodyHandler.prototype);
  13377. ReferenceHandler.prototype.handleNode = function(node) {
  13378. if (this.element) {
  13379. throw error('expected no sub nodes');
  13380. } else {
  13381. this.element = this.createReference(node);
  13382. }
  13383. return this;
  13384. };
  13385. ReferenceHandler.prototype.handleEnd = function() {
  13386. this.element.id = this.body;
  13387. };
  13388. ReferenceHandler.prototype.createReference = function(node) {
  13389. return {
  13390. property: this.property.ns.name,
  13391. id: ''
  13392. };
  13393. };
  13394. function ValueHandler(propertyDesc, element) {
  13395. this.element = element;
  13396. this.propertyDesc = propertyDesc;
  13397. }
  13398. ValueHandler.prototype = Object.create(BodyHandler.prototype);
  13399. ValueHandler.prototype.handleEnd = function() {
  13400. var value = this.body || '',
  13401. element = this.element,
  13402. propertyDesc = this.propertyDesc;
  13403. value = coerceType(propertyDesc.type, value);
  13404. if (propertyDesc.isMany) {
  13405. element.get(propertyDesc.name).push(value);
  13406. } else {
  13407. element.set(propertyDesc.name, value);
  13408. }
  13409. };
  13410. function BaseElementHandler() {}
  13411. BaseElementHandler.prototype = Object.create(BodyHandler.prototype);
  13412. BaseElementHandler.prototype.handleNode = function(node) {
  13413. var parser = this,
  13414. element = this.element;
  13415. if (!element) {
  13416. element = this.element = this.createElement(node);
  13417. this.context.addElement(element);
  13418. } else {
  13419. parser = this.handleChild(node);
  13420. }
  13421. return parser;
  13422. };
  13423. /**
  13424. * @class Reader.ElementHandler
  13425. *
  13426. */
  13427. function ElementHandler(model, typeName, context) {
  13428. this.model = model;
  13429. this.type = model.getType(typeName);
  13430. this.context = context;
  13431. }
  13432. ElementHandler.prototype = Object.create(BaseElementHandler.prototype);
  13433. ElementHandler.prototype.addReference = function(reference) {
  13434. this.context.addReference(reference);
  13435. };
  13436. ElementHandler.prototype.handleText = function(text) {
  13437. var element = this.element,
  13438. descriptor = getModdleDescriptor(element),
  13439. bodyProperty = descriptor.bodyProperty;
  13440. if (!bodyProperty) {
  13441. throw error('unexpected body text <' + text + '>');
  13442. }
  13443. BodyHandler.prototype.handleText.call(this, text);
  13444. };
  13445. ElementHandler.prototype.handleEnd = function() {
  13446. var value = this.body,
  13447. element = this.element,
  13448. descriptor = getModdleDescriptor(element),
  13449. bodyProperty = descriptor.bodyProperty;
  13450. if (bodyProperty && value !== undefined) {
  13451. value = coerceType(bodyProperty.type, value);
  13452. element.set(bodyProperty.name, value);
  13453. }
  13454. };
  13455. /**
  13456. * Create an instance of the model from the given node.
  13457. *
  13458. * @param {Element} node the xml node
  13459. */
  13460. ElementHandler.prototype.createElement = function(node) {
  13461. var attributes = node.attributes,
  13462. Type = this.type,
  13463. descriptor = getModdleDescriptor(Type),
  13464. context = this.context,
  13465. instance = new Type({}),
  13466. model = this.model,
  13467. propNameNs;
  13468. forEach$1(attributes, function(value, name) {
  13469. var prop = descriptor.propertiesByName[name],
  13470. values;
  13471. if (prop && prop.isReference) {
  13472. if (!prop.isMany) {
  13473. context.addReference({
  13474. element: instance,
  13475. property: prop.ns.name,
  13476. id: value
  13477. });
  13478. } else {
  13479. // IDREFS: parse references as whitespace-separated list
  13480. values = value.split(' ');
  13481. forEach$1(values, function(v) {
  13482. context.addReference({
  13483. element: instance,
  13484. property: prop.ns.name,
  13485. id: v
  13486. });
  13487. });
  13488. }
  13489. } else {
  13490. if (prop) {
  13491. value = coerceType(prop.type, value);
  13492. } else
  13493. if (name !== 'xmlns') {
  13494. propNameNs = parseName(name, descriptor.ns.prefix);
  13495. // check whether attribute is defined in a well-known namespace
  13496. // if that is the case we emit a warning to indicate potential misuse
  13497. if (model.getPackage(propNameNs.prefix)) {
  13498. context.addWarning({
  13499. message: 'unknown attribute <' + name + '>',
  13500. element: instance,
  13501. property: name,
  13502. value: value
  13503. });
  13504. }
  13505. }
  13506. instance.set(name, value);
  13507. }
  13508. });
  13509. return instance;
  13510. };
  13511. ElementHandler.prototype.getPropertyForNode = function(node) {
  13512. var name = node.name;
  13513. var nameNs = parseName(name);
  13514. var type = this.type,
  13515. model = this.model,
  13516. descriptor = getModdleDescriptor(type);
  13517. var propertyName = nameNs.name,
  13518. property = descriptor.propertiesByName[propertyName],
  13519. elementTypeName,
  13520. elementType;
  13521. // search for properties by name first
  13522. if (property && !property.isAttr) {
  13523. if (serializeAsType(property)) {
  13524. elementTypeName = node.attributes[XSI_TYPE];
  13525. // xsi type is optional, if it does not exists the
  13526. // default type is assumed
  13527. if (elementTypeName) {
  13528. // take possible type prefixes from XML
  13529. // into account, i.e.: xsi:type="t{ActualType}"
  13530. elementTypeName = normalizeXsiTypeName(elementTypeName, model);
  13531. elementType = model.getType(elementTypeName);
  13532. return assign$1({}, property, {
  13533. effectiveType: getModdleDescriptor(elementType).name
  13534. });
  13535. }
  13536. }
  13537. // search for properties by name first
  13538. return property;
  13539. }
  13540. var pkg = model.getPackage(nameNs.prefix);
  13541. if (pkg) {
  13542. elementTypeName = aliasToName(nameNs, pkg);
  13543. elementType = model.getType(elementTypeName);
  13544. // search for collection members later
  13545. property = find(descriptor.properties, function(p) {
  13546. return !p.isVirtual && !p.isReference && !p.isAttribute && elementType.hasType(p.type);
  13547. });
  13548. if (property) {
  13549. return assign$1({}, property, {
  13550. effectiveType: getModdleDescriptor(elementType).name
  13551. });
  13552. }
  13553. } else {
  13554. // parse unknown element (maybe extension)
  13555. property = find(descriptor.properties, function(p) {
  13556. return !p.isReference && !p.isAttribute && p.type === 'Element';
  13557. });
  13558. if (property) {
  13559. return property;
  13560. }
  13561. }
  13562. throw error('unrecognized element <' + nameNs.name + '>');
  13563. };
  13564. ElementHandler.prototype.toString = function() {
  13565. return 'ElementDescriptor[' + getModdleDescriptor(this.type).name + ']';
  13566. };
  13567. ElementHandler.prototype.valueHandler = function(propertyDesc, element) {
  13568. return new ValueHandler(propertyDesc, element);
  13569. };
  13570. ElementHandler.prototype.referenceHandler = function(propertyDesc) {
  13571. return new ReferenceHandler(propertyDesc, this.context);
  13572. };
  13573. ElementHandler.prototype.handler = function(type) {
  13574. if (type === 'Element') {
  13575. return new GenericElementHandler(this.model, type, this.context);
  13576. } else {
  13577. return new ElementHandler(this.model, type, this.context);
  13578. }
  13579. };
  13580. /**
  13581. * Handle the child element parsing
  13582. *
  13583. * @param {Element} node the xml node
  13584. */
  13585. ElementHandler.prototype.handleChild = function(node) {
  13586. var propertyDesc, type, element, childHandler;
  13587. propertyDesc = this.getPropertyForNode(node);
  13588. element = this.element;
  13589. type = propertyDesc.effectiveType || propertyDesc.type;
  13590. if (isSimple(type)) {
  13591. return this.valueHandler(propertyDesc, element);
  13592. }
  13593. if (propertyDesc.isReference) {
  13594. childHandler = this.referenceHandler(propertyDesc).handleNode(node);
  13595. } else {
  13596. childHandler = this.handler(type).handleNode(node);
  13597. }
  13598. var newElement = childHandler.element;
  13599. // child handles may decide to skip elements
  13600. // by not returning anything
  13601. if (newElement !== undefined) {
  13602. if (propertyDesc.isMany) {
  13603. element.get(propertyDesc.name).push(newElement);
  13604. } else {
  13605. element.set(propertyDesc.name, newElement);
  13606. }
  13607. if (propertyDesc.isReference) {
  13608. assign$1(newElement, {
  13609. element: element
  13610. });
  13611. this.context.addReference(newElement);
  13612. } else {
  13613. // establish child -> parent relationship
  13614. newElement.$parent = element;
  13615. }
  13616. }
  13617. return childHandler;
  13618. };
  13619. /**
  13620. * An element handler that performs special validation
  13621. * to ensure the node it gets initialized with matches
  13622. * the handlers type (namespace wise).
  13623. *
  13624. * @param {Moddle} model
  13625. * @param {String} typeName
  13626. * @param {Context} context
  13627. */
  13628. function RootElementHandler(model, typeName, context) {
  13629. ElementHandler.call(this, model, typeName, context);
  13630. }
  13631. RootElementHandler.prototype = Object.create(ElementHandler.prototype);
  13632. RootElementHandler.prototype.createElement = function(node) {
  13633. var name = node.name,
  13634. nameNs = parseName(name),
  13635. model = this.model,
  13636. type = this.type,
  13637. pkg = model.getPackage(nameNs.prefix),
  13638. typeName = pkg && aliasToName(nameNs, pkg) || name;
  13639. // verify the correct namespace if we parse
  13640. // the first element in the handler tree
  13641. //
  13642. // this ensures we don't mistakenly import wrong namespace elements
  13643. if (!type.hasType(typeName)) {
  13644. throw error('unexpected element <' + node.originalName + '>');
  13645. }
  13646. return ElementHandler.prototype.createElement.call(this, node);
  13647. };
  13648. function GenericElementHandler(model, typeName, context) {
  13649. this.model = model;
  13650. this.context = context;
  13651. }
  13652. GenericElementHandler.prototype = Object.create(BaseElementHandler.prototype);
  13653. GenericElementHandler.prototype.createElement = function(node) {
  13654. var name = node.name,
  13655. ns = parseName(name),
  13656. prefix = ns.prefix,
  13657. uri = node.ns[prefix + '$uri'],
  13658. attributes = node.attributes;
  13659. return this.model.createAny(name, uri, attributes);
  13660. };
  13661. GenericElementHandler.prototype.handleChild = function(node) {
  13662. var handler = new GenericElementHandler(this.model, 'Element', this.context).handleNode(node),
  13663. element = this.element;
  13664. var newElement = handler.element,
  13665. children;
  13666. if (newElement !== undefined) {
  13667. children = element.$children = element.$children || [];
  13668. children.push(newElement);
  13669. // establish child -> parent relationship
  13670. newElement.$parent = element;
  13671. }
  13672. return handler;
  13673. };
  13674. GenericElementHandler.prototype.handleEnd = function() {
  13675. if (this.body) {
  13676. this.element.$body = this.body;
  13677. }
  13678. };
  13679. /**
  13680. * A reader for a meta-model
  13681. *
  13682. * @param {Object} options
  13683. * @param {Model} options.model used to read xml files
  13684. * @param {Boolean} options.lax whether to make parse errors warnings
  13685. */
  13686. function Reader(options) {
  13687. if (options instanceof Moddle) {
  13688. options = {
  13689. model: options
  13690. };
  13691. }
  13692. assign$1(this, { lax: false }, options);
  13693. }
  13694. /**
  13695. * The fromXML result.
  13696. *
  13697. * @typedef {Object} ParseResult
  13698. *
  13699. * @property {ModdleElement} rootElement
  13700. * @property {Array<Object>} references
  13701. * @property {Array<Error>} warnings
  13702. * @property {Object} elementsById - a mapping containing each ID -> ModdleElement
  13703. */
  13704. /**
  13705. * The fromXML result.
  13706. *
  13707. * @typedef {Error} ParseError
  13708. *
  13709. * @property {Array<Error>} warnings
  13710. */
  13711. /**
  13712. * Parse the given XML into a moddle document tree.
  13713. *
  13714. * @param {String} xml
  13715. * @param {ElementHandler|Object} options or rootHandler
  13716. *
  13717. * @returns {Promise<ParseResult, ParseError>}
  13718. */
  13719. Reader.prototype.fromXML = function(xml, options, done) {
  13720. var rootHandler = options.rootHandler;
  13721. if (options instanceof ElementHandler) {
  13722. // root handler passed via (xml, { rootHandler: ElementHandler }, ...)
  13723. rootHandler = options;
  13724. options = {};
  13725. } else {
  13726. if (typeof options === 'string') {
  13727. // rootHandler passed via (xml, 'someString', ...)
  13728. rootHandler = this.handler(options);
  13729. options = {};
  13730. } else if (typeof rootHandler === 'string') {
  13731. // rootHandler passed via (xml, { rootHandler: 'someString' }, ...)
  13732. rootHandler = this.handler(rootHandler);
  13733. }
  13734. }
  13735. var model = this.model,
  13736. lax = this.lax;
  13737. var context = new Context(assign$1({}, options, { rootHandler: rootHandler })),
  13738. parser = new Parser({ proxy: true }),
  13739. stack = createStack();
  13740. rootHandler.context = context;
  13741. // push root handler
  13742. stack.push(rootHandler);
  13743. /**
  13744. * Handle error.
  13745. *
  13746. * @param {Error} err
  13747. * @param {Function} getContext
  13748. * @param {boolean} lax
  13749. *
  13750. * @return {boolean} true if handled
  13751. */
  13752. function handleError(err, getContext, lax) {
  13753. var ctx = getContext();
  13754. var line = ctx.line,
  13755. column = ctx.column,
  13756. data = ctx.data;
  13757. // we receive the full context data here,
  13758. // for elements trim down the information
  13759. // to the tag name, only
  13760. if (data.charAt(0) === '<' && data.indexOf(' ') !== -1) {
  13761. data = data.slice(0, data.indexOf(' ')) + '>';
  13762. }
  13763. var message =
  13764. 'unparsable content ' + (data ? data + ' ' : '') + 'detected\n\t' +
  13765. 'line: ' + line + '\n\t' +
  13766. 'column: ' + column + '\n\t' +
  13767. 'nested error: ' + err.message;
  13768. if (lax) {
  13769. context.addWarning({
  13770. message: message,
  13771. error: err
  13772. });
  13773. return true;
  13774. } else {
  13775. throw error(message);
  13776. }
  13777. }
  13778. function handleWarning(err, getContext) {
  13779. // just like handling errors in <lax=true> mode
  13780. return handleError(err, getContext, true);
  13781. }
  13782. /**
  13783. * Resolve collected references on parse end.
  13784. */
  13785. function resolveReferences() {
  13786. var elementsById = context.elementsById;
  13787. var references = context.references;
  13788. var i, r;
  13789. for (i = 0; (r = references[i]); i++) {
  13790. var element = r.element;
  13791. var reference = elementsById[r.id];
  13792. var property = getModdleDescriptor(element).propertiesByName[r.property];
  13793. if (!reference) {
  13794. context.addWarning({
  13795. message: 'unresolved reference <' + r.id + '>',
  13796. element: r.element,
  13797. property: r.property,
  13798. value: r.id
  13799. });
  13800. }
  13801. if (property.isMany) {
  13802. var collection = element.get(property.name),
  13803. idx = collection.indexOf(r);
  13804. // we replace an existing place holder (idx != -1) or
  13805. // append to the collection instead
  13806. if (idx === -1) {
  13807. idx = collection.length;
  13808. }
  13809. if (!reference) {
  13810. // remove unresolvable reference
  13811. collection.splice(idx, 1);
  13812. } else {
  13813. // add or update reference in collection
  13814. collection[idx] = reference;
  13815. }
  13816. } else {
  13817. element.set(property.name, reference);
  13818. }
  13819. }
  13820. }
  13821. function handleClose() {
  13822. stack.pop().handleEnd();
  13823. }
  13824. var PREAMBLE_START_PATTERN = /^<\?xml /i;
  13825. var ENCODING_PATTERN = / encoding="([^"]+)"/i;
  13826. var UTF_8_PATTERN = /^utf-8$/i;
  13827. function handleQuestion(question) {
  13828. if (!PREAMBLE_START_PATTERN.test(question)) {
  13829. return;
  13830. }
  13831. var match = ENCODING_PATTERN.exec(question);
  13832. var encoding = match && match[1];
  13833. if (!encoding || UTF_8_PATTERN.test(encoding)) {
  13834. return;
  13835. }
  13836. context.addWarning({
  13837. message:
  13838. 'unsupported document encoding <' + encoding + '>, ' +
  13839. 'falling back to UTF-8'
  13840. });
  13841. }
  13842. function handleOpen(node, getContext) {
  13843. var handler = stack.peek();
  13844. try {
  13845. stack.push(handler.handleNode(node));
  13846. } catch (err) {
  13847. if (handleError(err, getContext, lax)) {
  13848. stack.push(new NoopHandler());
  13849. }
  13850. }
  13851. }
  13852. function handleCData(text, getContext) {
  13853. try {
  13854. stack.peek().handleText(text);
  13855. } catch (err) {
  13856. handleWarning(err, getContext);
  13857. }
  13858. }
  13859. function handleText(text, getContext) {
  13860. // strip whitespace only nodes, i.e. before
  13861. // <!CDATA[ ... ]> sections and in between tags
  13862. if (!text.trim()) {
  13863. return;
  13864. }
  13865. handleCData(text, getContext);
  13866. }
  13867. var uriMap = model.getPackages().reduce(function(uriMap, p) {
  13868. uriMap[p.uri] = p.prefix;
  13869. return uriMap;
  13870. }, {
  13871. 'http://www.w3.org/XML/1998/namespace': 'xml' // add default xml ns
  13872. });
  13873. parser
  13874. .ns(uriMap)
  13875. .on('openTag', function(obj, decodeStr, selfClosing, getContext) {
  13876. // gracefully handle unparsable attributes (attrs=false)
  13877. var attrs = obj.attrs || {};
  13878. var decodedAttrs = Object.keys(attrs).reduce(function(d, key) {
  13879. var value = decodeStr(attrs[key]);
  13880. d[key] = value;
  13881. return d;
  13882. }, {});
  13883. var node = {
  13884. name: obj.name,
  13885. originalName: obj.originalName,
  13886. attributes: decodedAttrs,
  13887. ns: obj.ns
  13888. };
  13889. handleOpen(node, getContext);
  13890. })
  13891. .on('question', handleQuestion)
  13892. .on('closeTag', handleClose)
  13893. .on('cdata', handleCData)
  13894. .on('text', function(text, decodeEntities, getContext) {
  13895. handleText(decodeEntities(text), getContext);
  13896. })
  13897. .on('error', handleError)
  13898. .on('warn', handleWarning);
  13899. // async XML parsing to make sure the execution environment
  13900. // (node or brower) is kept responsive and that certain optimization
  13901. // strategies can kick in.
  13902. return new Promise(function(resolve, reject) {
  13903. var err;
  13904. try {
  13905. parser.parse(xml);
  13906. resolveReferences();
  13907. } catch (e) {
  13908. err = e;
  13909. }
  13910. var rootElement = rootHandler.element;
  13911. if (!err && !rootElement) {
  13912. err = error('failed to parse document as <' + rootHandler.type.$descriptor.name + '>');
  13913. }
  13914. var warnings = context.warnings;
  13915. var references = context.references;
  13916. var elementsById = context.elementsById;
  13917. if (err) {
  13918. err.warnings = warnings;
  13919. return reject(err);
  13920. } else {
  13921. return resolve({
  13922. rootElement: rootElement,
  13923. elementsById: elementsById,
  13924. references: references,
  13925. warnings: warnings
  13926. });
  13927. }
  13928. });
  13929. };
  13930. Reader.prototype.handler = function(name) {
  13931. return new RootElementHandler(this.model, name);
  13932. };
  13933. // helpers //////////////////////////
  13934. function createStack() {
  13935. var stack = [];
  13936. Object.defineProperty(stack, 'peek', {
  13937. value: function() {
  13938. return this[this.length - 1];
  13939. }
  13940. });
  13941. return stack;
  13942. }
  13943. var XML_PREAMBLE = '<?xml version="1.0" encoding="UTF-8"?>\n';
  13944. var ESCAPE_ATTR_CHARS = /<|>|'|"|&|\n\r|\n/g;
  13945. var ESCAPE_CHARS = /<|>|&/g;
  13946. function Namespaces(parent) {
  13947. var prefixMap = {};
  13948. var uriMap = {};
  13949. var used = {};
  13950. var wellknown = [];
  13951. var custom = [];
  13952. // API
  13953. this.byUri = function(uri) {
  13954. return uriMap[uri] || (
  13955. parent && parent.byUri(uri)
  13956. );
  13957. };
  13958. this.add = function(ns, isWellknown) {
  13959. uriMap[ns.uri] = ns;
  13960. if (isWellknown) {
  13961. wellknown.push(ns);
  13962. } else {
  13963. custom.push(ns);
  13964. }
  13965. this.mapPrefix(ns.prefix, ns.uri);
  13966. };
  13967. this.uriByPrefix = function(prefix) {
  13968. return prefixMap[prefix || 'xmlns'];
  13969. };
  13970. this.mapPrefix = function(prefix, uri) {
  13971. prefixMap[prefix || 'xmlns'] = uri;
  13972. };
  13973. this.getNSKey = function(ns) {
  13974. return (ns.prefix !== undefined) ? (ns.uri + '|' + ns.prefix) : ns.uri;
  13975. };
  13976. this.logUsed = function(ns) {
  13977. var uri = ns.uri;
  13978. var nsKey = this.getNSKey(ns);
  13979. used[nsKey] = this.byUri(uri);
  13980. // Inform parent recursively about the usage of this NS
  13981. if (parent) {
  13982. parent.logUsed(ns);
  13983. }
  13984. };
  13985. this.getUsed = function(ns) {
  13986. function isUsed(ns) {
  13987. var nsKey = self.getNSKey(ns);
  13988. return used[nsKey];
  13989. }
  13990. var self = this;
  13991. var allNs = [].concat(wellknown, custom);
  13992. return allNs.filter(isUsed);
  13993. };
  13994. }
  13995. function lower(string) {
  13996. return string.charAt(0).toLowerCase() + string.slice(1);
  13997. }
  13998. function nameToAlias(name, pkg) {
  13999. if (hasLowerCaseAlias(pkg)) {
  14000. return lower(name);
  14001. } else {
  14002. return name;
  14003. }
  14004. }
  14005. function inherits(ctor, superCtor) {
  14006. ctor.super_ = superCtor;
  14007. ctor.prototype = Object.create(superCtor.prototype, {
  14008. constructor: {
  14009. value: ctor,
  14010. enumerable: false,
  14011. writable: true,
  14012. configurable: true
  14013. }
  14014. });
  14015. }
  14016. function nsName(ns) {
  14017. if (isString(ns)) {
  14018. return ns;
  14019. } else {
  14020. return (ns.prefix ? ns.prefix + ':' : '') + ns.localName;
  14021. }
  14022. }
  14023. function getNsAttrs(namespaces) {
  14024. return namespaces.getUsed().filter(function(ns) {
  14025. // do not serialize built in <xml> namespace
  14026. return ns.prefix !== 'xml';
  14027. }).map(function(ns) {
  14028. var name = 'xmlns' + (ns.prefix ? ':' + ns.prefix : '');
  14029. return { name: name, value: ns.uri };
  14030. });
  14031. }
  14032. function getElementNs(ns, descriptor) {
  14033. if (descriptor.isGeneric) {
  14034. return assign$1({ localName: descriptor.ns.localName }, ns);
  14035. } else {
  14036. return assign$1({ localName: nameToAlias(descriptor.ns.localName, descriptor.$pkg) }, ns);
  14037. }
  14038. }
  14039. function getPropertyNs(ns, descriptor) {
  14040. return assign$1({ localName: descriptor.ns.localName }, ns);
  14041. }
  14042. function getSerializableProperties(element) {
  14043. var descriptor = element.$descriptor;
  14044. return filter(descriptor.properties, function(p) {
  14045. var name = p.name;
  14046. if (p.isVirtual) {
  14047. return false;
  14048. }
  14049. // do not serialize defaults
  14050. if (!has$1(element, name)) {
  14051. return false;
  14052. }
  14053. var value = element[name];
  14054. // do not serialize default equals
  14055. if (value === p.default) {
  14056. return false;
  14057. }
  14058. // do not serialize null properties
  14059. if (value === null) {
  14060. return false;
  14061. }
  14062. return p.isMany ? value.length : true;
  14063. });
  14064. }
  14065. var ESCAPE_ATTR_MAP = {
  14066. '\n': '#10',
  14067. '\n\r': '#10',
  14068. '"': '#34',
  14069. '\'': '#39',
  14070. '<': '#60',
  14071. '>': '#62',
  14072. '&': '#38'
  14073. };
  14074. var ESCAPE_MAP = {
  14075. '<': 'lt',
  14076. '>': 'gt',
  14077. '&': 'amp'
  14078. };
  14079. function escape(str, charPattern, replaceMap) {
  14080. // ensure we are handling strings here
  14081. str = isString(str) ? str : '' + str;
  14082. return str.replace(charPattern, function(s) {
  14083. return '&' + replaceMap[s] + ';';
  14084. });
  14085. }
  14086. /**
  14087. * Escape a string attribute to not contain any bad values (line breaks, '"', ...)
  14088. *
  14089. * @param {String} str the string to escape
  14090. * @return {String} the escaped string
  14091. */
  14092. function escapeAttr(str) {
  14093. return escape(str, ESCAPE_ATTR_CHARS, ESCAPE_ATTR_MAP);
  14094. }
  14095. function escapeBody(str) {
  14096. return escape(str, ESCAPE_CHARS, ESCAPE_MAP);
  14097. }
  14098. function filterAttributes(props) {
  14099. return filter(props, function(p) { return p.isAttr; });
  14100. }
  14101. function filterContained(props) {
  14102. return filter(props, function(p) { return !p.isAttr; });
  14103. }
  14104. function ReferenceSerializer(tagName) {
  14105. this.tagName = tagName;
  14106. }
  14107. ReferenceSerializer.prototype.build = function(element) {
  14108. this.element = element;
  14109. return this;
  14110. };
  14111. ReferenceSerializer.prototype.serializeTo = function(writer) {
  14112. writer
  14113. .appendIndent()
  14114. .append('<' + this.tagName + '>' + this.element.id + '</' + this.tagName + '>')
  14115. .appendNewLine();
  14116. };
  14117. function BodySerializer() {}
  14118. BodySerializer.prototype.serializeValue =
  14119. BodySerializer.prototype.serializeTo = function(writer) {
  14120. writer.append(
  14121. this.escape
  14122. ? escapeBody(this.value)
  14123. : this.value
  14124. );
  14125. };
  14126. BodySerializer.prototype.build = function(prop, value) {
  14127. this.value = value;
  14128. if (prop.type === 'String' && value.search(ESCAPE_CHARS) !== -1) {
  14129. this.escape = true;
  14130. }
  14131. return this;
  14132. };
  14133. function ValueSerializer(tagName) {
  14134. this.tagName = tagName;
  14135. }
  14136. inherits(ValueSerializer, BodySerializer);
  14137. ValueSerializer.prototype.serializeTo = function(writer) {
  14138. writer
  14139. .appendIndent()
  14140. .append('<' + this.tagName + '>');
  14141. this.serializeValue(writer);
  14142. writer
  14143. .append('</' + this.tagName + '>')
  14144. .appendNewLine();
  14145. };
  14146. function ElementSerializer(parent, propertyDescriptor) {
  14147. this.body = [];
  14148. this.attrs = [];
  14149. this.parent = parent;
  14150. this.propertyDescriptor = propertyDescriptor;
  14151. }
  14152. ElementSerializer.prototype.build = function(element) {
  14153. this.element = element;
  14154. var elementDescriptor = element.$descriptor,
  14155. propertyDescriptor = this.propertyDescriptor;
  14156. var otherAttrs,
  14157. properties;
  14158. var isGeneric = elementDescriptor.isGeneric;
  14159. if (isGeneric) {
  14160. otherAttrs = this.parseGeneric(element);
  14161. } else {
  14162. otherAttrs = this.parseNsAttributes(element);
  14163. }
  14164. if (propertyDescriptor) {
  14165. this.ns = this.nsPropertyTagName(propertyDescriptor);
  14166. } else {
  14167. this.ns = this.nsTagName(elementDescriptor);
  14168. }
  14169. // compute tag name
  14170. this.tagName = this.addTagName(this.ns);
  14171. if (!isGeneric) {
  14172. properties = getSerializableProperties(element);
  14173. this.parseAttributes(filterAttributes(properties));
  14174. this.parseContainments(filterContained(properties));
  14175. }
  14176. this.parseGenericAttributes(element, otherAttrs);
  14177. return this;
  14178. };
  14179. ElementSerializer.prototype.nsTagName = function(descriptor) {
  14180. var effectiveNs = this.logNamespaceUsed(descriptor.ns);
  14181. return getElementNs(effectiveNs, descriptor);
  14182. };
  14183. ElementSerializer.prototype.nsPropertyTagName = function(descriptor) {
  14184. var effectiveNs = this.logNamespaceUsed(descriptor.ns);
  14185. return getPropertyNs(effectiveNs, descriptor);
  14186. };
  14187. ElementSerializer.prototype.isLocalNs = function(ns) {
  14188. return ns.uri === this.ns.uri;
  14189. };
  14190. /**
  14191. * Get the actual ns attribute name for the given element.
  14192. *
  14193. * @param {Object} element
  14194. * @param {Boolean} [element.inherited=false]
  14195. *
  14196. * @return {Object} nsName
  14197. */
  14198. ElementSerializer.prototype.nsAttributeName = function(element) {
  14199. var ns;
  14200. if (isString(element)) {
  14201. ns = parseName(element);
  14202. } else {
  14203. ns = element.ns;
  14204. }
  14205. // return just local name for inherited attributes
  14206. if (element.inherited) {
  14207. return { localName: ns.localName };
  14208. }
  14209. // parse + log effective ns
  14210. var effectiveNs = this.logNamespaceUsed(ns);
  14211. // LOG ACTUAL namespace use
  14212. this.getNamespaces().logUsed(effectiveNs);
  14213. // strip prefix if same namespace like parent
  14214. if (this.isLocalNs(effectiveNs)) {
  14215. return { localName: ns.localName };
  14216. } else {
  14217. return assign$1({ localName: ns.localName }, effectiveNs);
  14218. }
  14219. };
  14220. ElementSerializer.prototype.parseGeneric = function(element) {
  14221. var self = this,
  14222. body = this.body;
  14223. var attributes = [];
  14224. forEach$1(element, function(val, key) {
  14225. var nonNsAttr;
  14226. if (key === '$body') {
  14227. body.push(new BodySerializer().build({ type: 'String' }, val));
  14228. } else
  14229. if (key === '$children') {
  14230. forEach$1(val, function(child) {
  14231. body.push(new ElementSerializer(self).build(child));
  14232. });
  14233. } else
  14234. if (key.indexOf('$') !== 0) {
  14235. nonNsAttr = self.parseNsAttribute(element, key, val);
  14236. if (nonNsAttr) {
  14237. attributes.push({ name: key, value: val });
  14238. }
  14239. }
  14240. });
  14241. return attributes;
  14242. };
  14243. ElementSerializer.prototype.parseNsAttribute = function(element, name, value) {
  14244. var model = element.$model;
  14245. var nameNs = parseName(name);
  14246. var ns;
  14247. // parse xmlns:foo="http://foo.bar"
  14248. if (nameNs.prefix === 'xmlns') {
  14249. ns = { prefix: nameNs.localName, uri: value };
  14250. }
  14251. // parse xmlns="http://foo.bar"
  14252. if (!nameNs.prefix && nameNs.localName === 'xmlns') {
  14253. ns = { uri: value };
  14254. }
  14255. if (!ns) {
  14256. return {
  14257. name: name,
  14258. value: value
  14259. };
  14260. }
  14261. if (model && model.getPackage(value)) {
  14262. // register well known namespace
  14263. this.logNamespace(ns, true, true);
  14264. } else {
  14265. // log custom namespace directly as used
  14266. var actualNs = this.logNamespaceUsed(ns, true);
  14267. this.getNamespaces().logUsed(actualNs);
  14268. }
  14269. };
  14270. /**
  14271. * Parse namespaces and return a list of left over generic attributes
  14272. *
  14273. * @param {Object} element
  14274. * @return {Array<Object>}
  14275. */
  14276. ElementSerializer.prototype.parseNsAttributes = function(element, attrs) {
  14277. var self = this;
  14278. var genericAttrs = element.$attrs;
  14279. var attributes = [];
  14280. // parse namespace attributes first
  14281. // and log them. push non namespace attributes to a list
  14282. // and process them later
  14283. forEach$1(genericAttrs, function(value, name) {
  14284. var nonNsAttr = self.parseNsAttribute(element, name, value);
  14285. if (nonNsAttr) {
  14286. attributes.push(nonNsAttr);
  14287. }
  14288. });
  14289. return attributes;
  14290. };
  14291. ElementSerializer.prototype.parseGenericAttributes = function(element, attributes) {
  14292. var self = this;
  14293. forEach$1(attributes, function(attr) {
  14294. // do not serialize xsi:type attribute
  14295. // it is set manually based on the actual implementation type
  14296. if (attr.name === XSI_TYPE) {
  14297. return;
  14298. }
  14299. try {
  14300. self.addAttribute(self.nsAttributeName(attr.name), attr.value);
  14301. } catch (e) {
  14302. /* global console */
  14303. console.warn(
  14304. 'missing namespace information for ',
  14305. attr.name, '=', attr.value, 'on', element,
  14306. e);
  14307. }
  14308. });
  14309. };
  14310. ElementSerializer.prototype.parseContainments = function(properties) {
  14311. var self = this,
  14312. body = this.body,
  14313. element = this.element;
  14314. forEach$1(properties, function(p) {
  14315. var value = element.get(p.name),
  14316. isReference = p.isReference,
  14317. isMany = p.isMany;
  14318. if (!isMany) {
  14319. value = [ value ];
  14320. }
  14321. if (p.isBody) {
  14322. body.push(new BodySerializer().build(p, value[0]));
  14323. } else
  14324. if (isSimple(p.type)) {
  14325. forEach$1(value, function(v) {
  14326. body.push(new ValueSerializer(self.addTagName(self.nsPropertyTagName(p))).build(p, v));
  14327. });
  14328. } else
  14329. if (isReference) {
  14330. forEach$1(value, function(v) {
  14331. body.push(new ReferenceSerializer(self.addTagName(self.nsPropertyTagName(p))).build(v));
  14332. });
  14333. } else {
  14334. // allow serialization via type
  14335. // rather than element name
  14336. var asType = serializeAsType(p),
  14337. asProperty = serializeAsProperty(p);
  14338. forEach$1(value, function(v) {
  14339. var serializer;
  14340. if (asType) {
  14341. serializer = new TypeSerializer(self, p);
  14342. } else
  14343. if (asProperty) {
  14344. serializer = new ElementSerializer(self, p);
  14345. } else {
  14346. serializer = new ElementSerializer(self);
  14347. }
  14348. body.push(serializer.build(v));
  14349. });
  14350. }
  14351. });
  14352. };
  14353. ElementSerializer.prototype.getNamespaces = function(local) {
  14354. var namespaces = this.namespaces,
  14355. parent = this.parent,
  14356. parentNamespaces;
  14357. if (!namespaces) {
  14358. parentNamespaces = parent && parent.getNamespaces();
  14359. if (local || !parentNamespaces) {
  14360. this.namespaces = namespaces = new Namespaces(parentNamespaces);
  14361. } else {
  14362. namespaces = parentNamespaces;
  14363. }
  14364. }
  14365. return namespaces;
  14366. };
  14367. ElementSerializer.prototype.logNamespace = function(ns, wellknown, local) {
  14368. var namespaces = this.getNamespaces(local);
  14369. var nsUri = ns.uri,
  14370. nsPrefix = ns.prefix;
  14371. var existing = namespaces.byUri(nsUri);
  14372. if (!existing || local) {
  14373. namespaces.add(ns, wellknown);
  14374. }
  14375. namespaces.mapPrefix(nsPrefix, nsUri);
  14376. return ns;
  14377. };
  14378. ElementSerializer.prototype.logNamespaceUsed = function(ns, local) {
  14379. var element = this.element,
  14380. model = element.$model,
  14381. namespaces = this.getNamespaces(local);
  14382. // ns may be
  14383. //
  14384. // * prefix only
  14385. // * prefix:uri
  14386. // * localName only
  14387. var prefix = ns.prefix,
  14388. uri = ns.uri,
  14389. newPrefix, idx,
  14390. wellknownUri;
  14391. // handle anonymous namespaces (elementForm=unqualified), cf. #23
  14392. if (!prefix && !uri) {
  14393. return { localName: ns.localName };
  14394. }
  14395. wellknownUri = DEFAULT_NS_MAP[prefix] || model && (model.getPackage(prefix) || {}).uri;
  14396. uri = uri || wellknownUri || namespaces.uriByPrefix(prefix);
  14397. if (!uri) {
  14398. throw new Error('no namespace uri given for prefix <' + prefix + '>');
  14399. }
  14400. ns = namespaces.byUri(uri);
  14401. if (!ns) {
  14402. newPrefix = prefix;
  14403. idx = 1;
  14404. // find a prefix that is not mapped yet
  14405. while (namespaces.uriByPrefix(newPrefix)) {
  14406. newPrefix = prefix + '_' + idx++;
  14407. }
  14408. ns = this.logNamespace({ prefix: newPrefix, uri: uri }, wellknownUri === uri);
  14409. }
  14410. if (prefix) {
  14411. namespaces.mapPrefix(prefix, uri);
  14412. }
  14413. return ns;
  14414. };
  14415. ElementSerializer.prototype.parseAttributes = function(properties) {
  14416. var self = this,
  14417. element = this.element;
  14418. forEach$1(properties, function(p) {
  14419. var value = element.get(p.name);
  14420. if (p.isReference) {
  14421. if (!p.isMany) {
  14422. value = value.id;
  14423. }
  14424. else {
  14425. var values = [];
  14426. forEach$1(value, function(v) {
  14427. values.push(v.id);
  14428. });
  14429. // IDREFS is a whitespace-separated list of references.
  14430. value = values.join(' ');
  14431. }
  14432. }
  14433. self.addAttribute(self.nsAttributeName(p), value);
  14434. });
  14435. };
  14436. ElementSerializer.prototype.addTagName = function(nsTagName) {
  14437. var actualNs = this.logNamespaceUsed(nsTagName);
  14438. this.getNamespaces().logUsed(actualNs);
  14439. return nsName(nsTagName);
  14440. };
  14441. ElementSerializer.prototype.addAttribute = function(name, value) {
  14442. var attrs = this.attrs;
  14443. if (isString(value)) {
  14444. value = escapeAttr(value);
  14445. }
  14446. // de-duplicate attributes
  14447. // https://github.com/bpmn-io/moddle-xml/issues/66
  14448. var idx = findIndex(attrs, function(element) {
  14449. return (
  14450. element.name.localName === name.localName &&
  14451. element.name.uri === name.uri &&
  14452. element.name.prefix === name.prefix
  14453. );
  14454. });
  14455. var attr = { name: name, value: value };
  14456. if (idx !== -1) {
  14457. attrs.splice(idx, 1, attr);
  14458. } else {
  14459. attrs.push(attr);
  14460. }
  14461. };
  14462. ElementSerializer.prototype.serializeAttributes = function(writer) {
  14463. var attrs = this.attrs,
  14464. namespaces = this.namespaces;
  14465. if (namespaces) {
  14466. attrs = getNsAttrs(namespaces).concat(attrs);
  14467. }
  14468. forEach$1(attrs, function(a) {
  14469. writer
  14470. .append(' ')
  14471. .append(nsName(a.name)).append('="').append(a.value).append('"');
  14472. });
  14473. };
  14474. ElementSerializer.prototype.serializeTo = function(writer) {
  14475. var firstBody = this.body[0],
  14476. indent = firstBody && firstBody.constructor !== BodySerializer;
  14477. writer
  14478. .appendIndent()
  14479. .append('<' + this.tagName);
  14480. this.serializeAttributes(writer);
  14481. writer.append(firstBody ? '>' : ' />');
  14482. if (firstBody) {
  14483. if (indent) {
  14484. writer
  14485. .appendNewLine()
  14486. .indent();
  14487. }
  14488. forEach$1(this.body, function(b) {
  14489. b.serializeTo(writer);
  14490. });
  14491. if (indent) {
  14492. writer
  14493. .unindent()
  14494. .appendIndent();
  14495. }
  14496. writer.append('</' + this.tagName + '>');
  14497. }
  14498. writer.appendNewLine();
  14499. };
  14500. /**
  14501. * A serializer for types that handles serialization of data types
  14502. */
  14503. function TypeSerializer(parent, propertyDescriptor) {
  14504. ElementSerializer.call(this, parent, propertyDescriptor);
  14505. }
  14506. inherits(TypeSerializer, ElementSerializer);
  14507. TypeSerializer.prototype.parseNsAttributes = function(element) {
  14508. // extracted attributes
  14509. var attributes = ElementSerializer.prototype.parseNsAttributes.call(this, element);
  14510. var descriptor = element.$descriptor;
  14511. // only serialize xsi:type if necessary
  14512. if (descriptor.name === this.propertyDescriptor.type) {
  14513. return attributes;
  14514. }
  14515. var typeNs = this.typeNs = this.nsTagName(descriptor);
  14516. this.getNamespaces().logUsed(this.typeNs);
  14517. // add xsi:type attribute to represent the elements
  14518. // actual type
  14519. var pkg = element.$model.getPackage(typeNs.uri),
  14520. typePrefix = (pkg.xml && pkg.xml.typePrefix) || '';
  14521. this.addAttribute(
  14522. this.nsAttributeName(XSI_TYPE),
  14523. (typeNs.prefix ? typeNs.prefix + ':' : '') + typePrefix + descriptor.ns.localName
  14524. );
  14525. return attributes;
  14526. };
  14527. TypeSerializer.prototype.isLocalNs = function(ns) {
  14528. return ns.uri === (this.typeNs || this.ns).uri;
  14529. };
  14530. function SavingWriter() {
  14531. this.value = '';
  14532. this.write = function(str) {
  14533. this.value += str;
  14534. };
  14535. }
  14536. function FormatingWriter(out, format) {
  14537. var indent = [ '' ];
  14538. this.append = function(str) {
  14539. out.write(str);
  14540. return this;
  14541. };
  14542. this.appendNewLine = function() {
  14543. if (format) {
  14544. out.write('\n');
  14545. }
  14546. return this;
  14547. };
  14548. this.appendIndent = function() {
  14549. if (format) {
  14550. out.write(indent.join(' '));
  14551. }
  14552. return this;
  14553. };
  14554. this.indent = function() {
  14555. indent.push('');
  14556. return this;
  14557. };
  14558. this.unindent = function() {
  14559. indent.pop();
  14560. return this;
  14561. };
  14562. }
  14563. /**
  14564. * A writer for meta-model backed document trees
  14565. *
  14566. * @param {Object} options output options to pass into the writer
  14567. */
  14568. function Writer(options) {
  14569. options = assign$1({ format: false, preamble: true }, options || {});
  14570. function toXML(tree, writer) {
  14571. var internalWriter = writer || new SavingWriter();
  14572. var formatingWriter = new FormatingWriter(internalWriter, options.format);
  14573. if (options.preamble) {
  14574. formatingWriter.append(XML_PREAMBLE);
  14575. }
  14576. new ElementSerializer().build(tree).serializeTo(formatingWriter);
  14577. if (!writer) {
  14578. return internalWriter.value;
  14579. }
  14580. }
  14581. return {
  14582. toXML: toXML
  14583. };
  14584. }
  14585. /**
  14586. * A sub class of {@link Moddle} with support for import and export of BPMN 2.0 xml files.
  14587. *
  14588. * @class BpmnModdle
  14589. * @extends Moddle
  14590. *
  14591. * @param {Object|Array} packages to use for instantiating the model
  14592. * @param {Object} [options] additional options to pass over
  14593. */
  14594. function BpmnModdle(packages, options) {
  14595. Moddle.call(this, packages, options);
  14596. }
  14597. BpmnModdle.prototype = Object.create(Moddle.prototype);
  14598. /**
  14599. * The fromXML result.
  14600. *
  14601. * @typedef {Object} ParseResult
  14602. *
  14603. * @property {ModdleElement} rootElement
  14604. * @property {Array<Object>} references
  14605. * @property {Array<Error>} warnings
  14606. * @property {Object} elementsById - a mapping containing each ID -> ModdleElement
  14607. */
  14608. /**
  14609. * The fromXML error.
  14610. *
  14611. * @typedef {Error} ParseError
  14612. *
  14613. * @property {Array<Error>} warnings
  14614. */
  14615. /**
  14616. * Instantiates a BPMN model tree from a given xml string.
  14617. *
  14618. * @param {String} xmlStr
  14619. * @param {String} [typeName='bpmn:Definitions'] name of the root element
  14620. * @param {Object} [options] options to pass to the underlying reader
  14621. *
  14622. * @returns {Promise<ParseResult, ParseError>}
  14623. */
  14624. BpmnModdle.prototype.fromXML = function(xmlStr, typeName, options) {
  14625. if (!isString(typeName)) {
  14626. options = typeName;
  14627. typeName = 'bpmn:Definitions';
  14628. }
  14629. var reader = new Reader(assign$1({ model: this, lax: true }, options));
  14630. var rootHandler = reader.handler(typeName);
  14631. return reader.fromXML(xmlStr, rootHandler);
  14632. };
  14633. /**
  14634. * The toXML result.
  14635. *
  14636. * @typedef {Object} SerializationResult
  14637. *
  14638. * @property {String} xml
  14639. */
  14640. /**
  14641. * Serializes a BPMN 2.0 object tree to XML.
  14642. *
  14643. * @param {String} element the root element, typically an instance of `bpmn:Definitions`
  14644. * @param {Object} [options] to pass to the underlying writer
  14645. *
  14646. * @returns {Promise<SerializationResult, Error>}
  14647. */
  14648. BpmnModdle.prototype.toXML = function(element, options) {
  14649. var writer = new Writer(options);
  14650. return new Promise(function(resolve, reject) {
  14651. try {
  14652. var result = writer.toXML(element);
  14653. return resolve({
  14654. xml: result
  14655. });
  14656. } catch (err) {
  14657. return reject(err);
  14658. }
  14659. });
  14660. };
  14661. var name$5 = "BPMN20";
  14662. var uri$5 = "http://www.omg.org/spec/BPMN/20100524/MODEL";
  14663. var prefix$5 = "bpmn";
  14664. var associations$5 = [
  14665. ];
  14666. var types$5 = [
  14667. {
  14668. name: "Interface",
  14669. superClass: [
  14670. "RootElement"
  14671. ],
  14672. properties: [
  14673. {
  14674. name: "name",
  14675. isAttr: true,
  14676. type: "String"
  14677. },
  14678. {
  14679. name: "operations",
  14680. type: "Operation",
  14681. isMany: true
  14682. },
  14683. {
  14684. name: "implementationRef",
  14685. isAttr: true,
  14686. type: "String"
  14687. }
  14688. ]
  14689. },
  14690. {
  14691. name: "Operation",
  14692. superClass: [
  14693. "BaseElement"
  14694. ],
  14695. properties: [
  14696. {
  14697. name: "name",
  14698. isAttr: true,
  14699. type: "String"
  14700. },
  14701. {
  14702. name: "inMessageRef",
  14703. type: "Message",
  14704. isReference: true
  14705. },
  14706. {
  14707. name: "outMessageRef",
  14708. type: "Message",
  14709. isReference: true
  14710. },
  14711. {
  14712. name: "errorRef",
  14713. type: "Error",
  14714. isMany: true,
  14715. isReference: true
  14716. },
  14717. {
  14718. name: "implementationRef",
  14719. isAttr: true,
  14720. type: "String"
  14721. }
  14722. ]
  14723. },
  14724. {
  14725. name: "EndPoint",
  14726. superClass: [
  14727. "RootElement"
  14728. ]
  14729. },
  14730. {
  14731. name: "Auditing",
  14732. superClass: [
  14733. "BaseElement"
  14734. ]
  14735. },
  14736. {
  14737. name: "GlobalTask",
  14738. superClass: [
  14739. "CallableElement"
  14740. ],
  14741. properties: [
  14742. {
  14743. name: "resources",
  14744. type: "ResourceRole",
  14745. isMany: true
  14746. }
  14747. ]
  14748. },
  14749. {
  14750. name: "Monitoring",
  14751. superClass: [
  14752. "BaseElement"
  14753. ]
  14754. },
  14755. {
  14756. name: "Performer",
  14757. superClass: [
  14758. "ResourceRole"
  14759. ]
  14760. },
  14761. {
  14762. name: "Process",
  14763. superClass: [
  14764. "FlowElementsContainer",
  14765. "CallableElement"
  14766. ],
  14767. properties: [
  14768. {
  14769. name: "processType",
  14770. type: "ProcessType",
  14771. isAttr: true
  14772. },
  14773. {
  14774. name: "isClosed",
  14775. isAttr: true,
  14776. type: "Boolean"
  14777. },
  14778. {
  14779. name: "auditing",
  14780. type: "Auditing"
  14781. },
  14782. {
  14783. name: "monitoring",
  14784. type: "Monitoring"
  14785. },
  14786. {
  14787. name: "properties",
  14788. type: "Property",
  14789. isMany: true
  14790. },
  14791. {
  14792. name: "laneSets",
  14793. isMany: true,
  14794. replaces: "FlowElementsContainer#laneSets",
  14795. type: "LaneSet"
  14796. },
  14797. {
  14798. name: "flowElements",
  14799. isMany: true,
  14800. replaces: "FlowElementsContainer#flowElements",
  14801. type: "FlowElement"
  14802. },
  14803. {
  14804. name: "artifacts",
  14805. type: "Artifact",
  14806. isMany: true
  14807. },
  14808. {
  14809. name: "resources",
  14810. type: "ResourceRole",
  14811. isMany: true
  14812. },
  14813. {
  14814. name: "correlationSubscriptions",
  14815. type: "CorrelationSubscription",
  14816. isMany: true
  14817. },
  14818. {
  14819. name: "supports",
  14820. type: "Process",
  14821. isMany: true,
  14822. isReference: true
  14823. },
  14824. {
  14825. name: "definitionalCollaborationRef",
  14826. type: "Collaboration",
  14827. isAttr: true,
  14828. isReference: true
  14829. },
  14830. {
  14831. name: "isExecutable",
  14832. isAttr: true,
  14833. type: "Boolean"
  14834. }
  14835. ]
  14836. },
  14837. {
  14838. name: "LaneSet",
  14839. superClass: [
  14840. "BaseElement"
  14841. ],
  14842. properties: [
  14843. {
  14844. name: "lanes",
  14845. type: "Lane",
  14846. isMany: true
  14847. },
  14848. {
  14849. name: "name",
  14850. isAttr: true,
  14851. type: "String"
  14852. }
  14853. ]
  14854. },
  14855. {
  14856. name: "Lane",
  14857. superClass: [
  14858. "BaseElement"
  14859. ],
  14860. properties: [
  14861. {
  14862. name: "name",
  14863. isAttr: true,
  14864. type: "String"
  14865. },
  14866. {
  14867. name: "partitionElementRef",
  14868. type: "BaseElement",
  14869. isAttr: true,
  14870. isReference: true
  14871. },
  14872. {
  14873. name: "partitionElement",
  14874. type: "BaseElement"
  14875. },
  14876. {
  14877. name: "flowNodeRef",
  14878. type: "FlowNode",
  14879. isMany: true,
  14880. isReference: true
  14881. },
  14882. {
  14883. name: "childLaneSet",
  14884. type: "LaneSet",
  14885. xml: {
  14886. serialize: "xsi:type"
  14887. }
  14888. }
  14889. ]
  14890. },
  14891. {
  14892. name: "GlobalManualTask",
  14893. superClass: [
  14894. "GlobalTask"
  14895. ]
  14896. },
  14897. {
  14898. name: "ManualTask",
  14899. superClass: [
  14900. "Task"
  14901. ]
  14902. },
  14903. {
  14904. name: "UserTask",
  14905. superClass: [
  14906. "Task"
  14907. ],
  14908. properties: [
  14909. {
  14910. name: "renderings",
  14911. type: "Rendering",
  14912. isMany: true
  14913. },
  14914. {
  14915. name: "implementation",
  14916. isAttr: true,
  14917. type: "String"
  14918. }
  14919. ]
  14920. },
  14921. {
  14922. name: "Rendering",
  14923. superClass: [
  14924. "BaseElement"
  14925. ]
  14926. },
  14927. {
  14928. name: "HumanPerformer",
  14929. superClass: [
  14930. "Performer"
  14931. ]
  14932. },
  14933. {
  14934. name: "PotentialOwner",
  14935. superClass: [
  14936. "HumanPerformer"
  14937. ]
  14938. },
  14939. {
  14940. name: "GlobalUserTask",
  14941. superClass: [
  14942. "GlobalTask"
  14943. ],
  14944. properties: [
  14945. {
  14946. name: "implementation",
  14947. isAttr: true,
  14948. type: "String"
  14949. },
  14950. {
  14951. name: "renderings",
  14952. type: "Rendering",
  14953. isMany: true
  14954. }
  14955. ]
  14956. },
  14957. {
  14958. name: "Gateway",
  14959. isAbstract: true,
  14960. superClass: [
  14961. "FlowNode"
  14962. ],
  14963. properties: [
  14964. {
  14965. name: "gatewayDirection",
  14966. type: "GatewayDirection",
  14967. "default": "Unspecified",
  14968. isAttr: true
  14969. }
  14970. ]
  14971. },
  14972. {
  14973. name: "EventBasedGateway",
  14974. superClass: [
  14975. "Gateway"
  14976. ],
  14977. properties: [
  14978. {
  14979. name: "instantiate",
  14980. "default": false,
  14981. isAttr: true,
  14982. type: "Boolean"
  14983. },
  14984. {
  14985. name: "eventGatewayType",
  14986. type: "EventBasedGatewayType",
  14987. isAttr: true,
  14988. "default": "Exclusive"
  14989. }
  14990. ]
  14991. },
  14992. {
  14993. name: "ComplexGateway",
  14994. superClass: [
  14995. "Gateway"
  14996. ],
  14997. properties: [
  14998. {
  14999. name: "activationCondition",
  15000. type: "Expression",
  15001. xml: {
  15002. serialize: "xsi:type"
  15003. }
  15004. },
  15005. {
  15006. name: "default",
  15007. type: "SequenceFlow",
  15008. isAttr: true,
  15009. isReference: true
  15010. }
  15011. ]
  15012. },
  15013. {
  15014. name: "ExclusiveGateway",
  15015. superClass: [
  15016. "Gateway"
  15017. ],
  15018. properties: [
  15019. {
  15020. name: "default",
  15021. type: "SequenceFlow",
  15022. isAttr: true,
  15023. isReference: true
  15024. }
  15025. ]
  15026. },
  15027. {
  15028. name: "InclusiveGateway",
  15029. superClass: [
  15030. "Gateway"
  15031. ],
  15032. properties: [
  15033. {
  15034. name: "default",
  15035. type: "SequenceFlow",
  15036. isAttr: true,
  15037. isReference: true
  15038. }
  15039. ]
  15040. },
  15041. {
  15042. name: "ParallelGateway",
  15043. superClass: [
  15044. "Gateway"
  15045. ]
  15046. },
  15047. {
  15048. name: "RootElement",
  15049. isAbstract: true,
  15050. superClass: [
  15051. "BaseElement"
  15052. ]
  15053. },
  15054. {
  15055. name: "Relationship",
  15056. superClass: [
  15057. "BaseElement"
  15058. ],
  15059. properties: [
  15060. {
  15061. name: "type",
  15062. isAttr: true,
  15063. type: "String"
  15064. },
  15065. {
  15066. name: "direction",
  15067. type: "RelationshipDirection",
  15068. isAttr: true
  15069. },
  15070. {
  15071. name: "source",
  15072. isMany: true,
  15073. isReference: true,
  15074. type: "Element"
  15075. },
  15076. {
  15077. name: "target",
  15078. isMany: true,
  15079. isReference: true,
  15080. type: "Element"
  15081. }
  15082. ]
  15083. },
  15084. {
  15085. name: "BaseElement",
  15086. isAbstract: true,
  15087. properties: [
  15088. {
  15089. name: "id",
  15090. isAttr: true,
  15091. type: "String",
  15092. isId: true
  15093. },
  15094. {
  15095. name: "documentation",
  15096. type: "Documentation",
  15097. isMany: true
  15098. },
  15099. {
  15100. name: "extensionDefinitions",
  15101. type: "ExtensionDefinition",
  15102. isMany: true,
  15103. isReference: true
  15104. },
  15105. {
  15106. name: "extensionElements",
  15107. type: "ExtensionElements"
  15108. }
  15109. ]
  15110. },
  15111. {
  15112. name: "Extension",
  15113. properties: [
  15114. {
  15115. name: "mustUnderstand",
  15116. "default": false,
  15117. isAttr: true,
  15118. type: "Boolean"
  15119. },
  15120. {
  15121. name: "definition",
  15122. type: "ExtensionDefinition",
  15123. isAttr: true,
  15124. isReference: true
  15125. }
  15126. ]
  15127. },
  15128. {
  15129. name: "ExtensionDefinition",
  15130. properties: [
  15131. {
  15132. name: "name",
  15133. isAttr: true,
  15134. type: "String"
  15135. },
  15136. {
  15137. name: "extensionAttributeDefinitions",
  15138. type: "ExtensionAttributeDefinition",
  15139. isMany: true
  15140. }
  15141. ]
  15142. },
  15143. {
  15144. name: "ExtensionAttributeDefinition",
  15145. properties: [
  15146. {
  15147. name: "name",
  15148. isAttr: true,
  15149. type: "String"
  15150. },
  15151. {
  15152. name: "type",
  15153. isAttr: true,
  15154. type: "String"
  15155. },
  15156. {
  15157. name: "isReference",
  15158. "default": false,
  15159. isAttr: true,
  15160. type: "Boolean"
  15161. },
  15162. {
  15163. name: "extensionDefinition",
  15164. type: "ExtensionDefinition",
  15165. isAttr: true,
  15166. isReference: true
  15167. }
  15168. ]
  15169. },
  15170. {
  15171. name: "ExtensionElements",
  15172. properties: [
  15173. {
  15174. name: "valueRef",
  15175. isAttr: true,
  15176. isReference: true,
  15177. type: "Element"
  15178. },
  15179. {
  15180. name: "values",
  15181. type: "Element",
  15182. isMany: true
  15183. },
  15184. {
  15185. name: "extensionAttributeDefinition",
  15186. type: "ExtensionAttributeDefinition",
  15187. isAttr: true,
  15188. isReference: true
  15189. }
  15190. ]
  15191. },
  15192. {
  15193. name: "Documentation",
  15194. superClass: [
  15195. "BaseElement"
  15196. ],
  15197. properties: [
  15198. {
  15199. name: "text",
  15200. type: "String",
  15201. isBody: true
  15202. },
  15203. {
  15204. name: "textFormat",
  15205. "default": "text/plain",
  15206. isAttr: true,
  15207. type: "String"
  15208. }
  15209. ]
  15210. },
  15211. {
  15212. name: "Event",
  15213. isAbstract: true,
  15214. superClass: [
  15215. "FlowNode",
  15216. "InteractionNode"
  15217. ],
  15218. properties: [
  15219. {
  15220. name: "properties",
  15221. type: "Property",
  15222. isMany: true
  15223. }
  15224. ]
  15225. },
  15226. {
  15227. name: "IntermediateCatchEvent",
  15228. superClass: [
  15229. "CatchEvent"
  15230. ]
  15231. },
  15232. {
  15233. name: "IntermediateThrowEvent",
  15234. superClass: [
  15235. "ThrowEvent"
  15236. ]
  15237. },
  15238. {
  15239. name: "EndEvent",
  15240. superClass: [
  15241. "ThrowEvent"
  15242. ]
  15243. },
  15244. {
  15245. name: "StartEvent",
  15246. superClass: [
  15247. "CatchEvent"
  15248. ],
  15249. properties: [
  15250. {
  15251. name: "isInterrupting",
  15252. "default": true,
  15253. isAttr: true,
  15254. type: "Boolean"
  15255. }
  15256. ]
  15257. },
  15258. {
  15259. name: "ThrowEvent",
  15260. isAbstract: true,
  15261. superClass: [
  15262. "Event"
  15263. ],
  15264. properties: [
  15265. {
  15266. name: "dataInputs",
  15267. type: "DataInput",
  15268. isMany: true
  15269. },
  15270. {
  15271. name: "dataInputAssociations",
  15272. type: "DataInputAssociation",
  15273. isMany: true
  15274. },
  15275. {
  15276. name: "inputSet",
  15277. type: "InputSet"
  15278. },
  15279. {
  15280. name: "eventDefinitions",
  15281. type: "EventDefinition",
  15282. isMany: true
  15283. },
  15284. {
  15285. name: "eventDefinitionRef",
  15286. type: "EventDefinition",
  15287. isMany: true,
  15288. isReference: true
  15289. }
  15290. ]
  15291. },
  15292. {
  15293. name: "CatchEvent",
  15294. isAbstract: true,
  15295. superClass: [
  15296. "Event"
  15297. ],
  15298. properties: [
  15299. {
  15300. name: "parallelMultiple",
  15301. isAttr: true,
  15302. type: "Boolean",
  15303. "default": false
  15304. },
  15305. {
  15306. name: "dataOutputs",
  15307. type: "DataOutput",
  15308. isMany: true
  15309. },
  15310. {
  15311. name: "dataOutputAssociations",
  15312. type: "DataOutputAssociation",
  15313. isMany: true
  15314. },
  15315. {
  15316. name: "outputSet",
  15317. type: "OutputSet"
  15318. },
  15319. {
  15320. name: "eventDefinitions",
  15321. type: "EventDefinition",
  15322. isMany: true
  15323. },
  15324. {
  15325. name: "eventDefinitionRef",
  15326. type: "EventDefinition",
  15327. isMany: true,
  15328. isReference: true
  15329. }
  15330. ]
  15331. },
  15332. {
  15333. name: "BoundaryEvent",
  15334. superClass: [
  15335. "CatchEvent"
  15336. ],
  15337. properties: [
  15338. {
  15339. name: "cancelActivity",
  15340. "default": true,
  15341. isAttr: true,
  15342. type: "Boolean"
  15343. },
  15344. {
  15345. name: "attachedToRef",
  15346. type: "Activity",
  15347. isAttr: true,
  15348. isReference: true
  15349. }
  15350. ]
  15351. },
  15352. {
  15353. name: "EventDefinition",
  15354. isAbstract: true,
  15355. superClass: [
  15356. "RootElement"
  15357. ]
  15358. },
  15359. {
  15360. name: "CancelEventDefinition",
  15361. superClass: [
  15362. "EventDefinition"
  15363. ]
  15364. },
  15365. {
  15366. name: "ErrorEventDefinition",
  15367. superClass: [
  15368. "EventDefinition"
  15369. ],
  15370. properties: [
  15371. {
  15372. name: "errorRef",
  15373. type: "Error",
  15374. isAttr: true,
  15375. isReference: true
  15376. }
  15377. ]
  15378. },
  15379. {
  15380. name: "TerminateEventDefinition",
  15381. superClass: [
  15382. "EventDefinition"
  15383. ]
  15384. },
  15385. {
  15386. name: "EscalationEventDefinition",
  15387. superClass: [
  15388. "EventDefinition"
  15389. ],
  15390. properties: [
  15391. {
  15392. name: "escalationRef",
  15393. type: "Escalation",
  15394. isAttr: true,
  15395. isReference: true
  15396. }
  15397. ]
  15398. },
  15399. {
  15400. name: "Escalation",
  15401. properties: [
  15402. {
  15403. name: "structureRef",
  15404. type: "ItemDefinition",
  15405. isAttr: true,
  15406. isReference: true
  15407. },
  15408. {
  15409. name: "name",
  15410. isAttr: true,
  15411. type: "String"
  15412. },
  15413. {
  15414. name: "escalationCode",
  15415. isAttr: true,
  15416. type: "String"
  15417. }
  15418. ],
  15419. superClass: [
  15420. "RootElement"
  15421. ]
  15422. },
  15423. {
  15424. name: "CompensateEventDefinition",
  15425. superClass: [
  15426. "EventDefinition"
  15427. ],
  15428. properties: [
  15429. {
  15430. name: "waitForCompletion",
  15431. isAttr: true,
  15432. type: "Boolean",
  15433. "default": true
  15434. },
  15435. {
  15436. name: "activityRef",
  15437. type: "Activity",
  15438. isAttr: true,
  15439. isReference: true
  15440. }
  15441. ]
  15442. },
  15443. {
  15444. name: "TimerEventDefinition",
  15445. superClass: [
  15446. "EventDefinition"
  15447. ],
  15448. properties: [
  15449. {
  15450. name: "timeDate",
  15451. type: "Expression",
  15452. xml: {
  15453. serialize: "xsi:type"
  15454. }
  15455. },
  15456. {
  15457. name: "timeCycle",
  15458. type: "Expression",
  15459. xml: {
  15460. serialize: "xsi:type"
  15461. }
  15462. },
  15463. {
  15464. name: "timeDuration",
  15465. type: "Expression",
  15466. xml: {
  15467. serialize: "xsi:type"
  15468. }
  15469. }
  15470. ]
  15471. },
  15472. {
  15473. name: "LinkEventDefinition",
  15474. superClass: [
  15475. "EventDefinition"
  15476. ],
  15477. properties: [
  15478. {
  15479. name: "name",
  15480. isAttr: true,
  15481. type: "String"
  15482. },
  15483. {
  15484. name: "target",
  15485. type: "LinkEventDefinition",
  15486. isReference: true
  15487. },
  15488. {
  15489. name: "source",
  15490. type: "LinkEventDefinition",
  15491. isMany: true,
  15492. isReference: true
  15493. }
  15494. ]
  15495. },
  15496. {
  15497. name: "MessageEventDefinition",
  15498. superClass: [
  15499. "EventDefinition"
  15500. ],
  15501. properties: [
  15502. {
  15503. name: "messageRef",
  15504. type: "Message",
  15505. isAttr: true,
  15506. isReference: true
  15507. },
  15508. {
  15509. name: "operationRef",
  15510. type: "Operation",
  15511. isAttr: true,
  15512. isReference: true
  15513. }
  15514. ]
  15515. },
  15516. {
  15517. name: "ConditionalEventDefinition",
  15518. superClass: [
  15519. "EventDefinition"
  15520. ],
  15521. properties: [
  15522. {
  15523. name: "condition",
  15524. type: "Expression",
  15525. xml: {
  15526. serialize: "xsi:type"
  15527. }
  15528. }
  15529. ]
  15530. },
  15531. {
  15532. name: "SignalEventDefinition",
  15533. superClass: [
  15534. "EventDefinition"
  15535. ],
  15536. properties: [
  15537. {
  15538. name: "signalRef",
  15539. type: "Signal",
  15540. isAttr: true,
  15541. isReference: true
  15542. }
  15543. ]
  15544. },
  15545. {
  15546. name: "Signal",
  15547. superClass: [
  15548. "RootElement"
  15549. ],
  15550. properties: [
  15551. {
  15552. name: "structureRef",
  15553. type: "ItemDefinition",
  15554. isAttr: true,
  15555. isReference: true
  15556. },
  15557. {
  15558. name: "name",
  15559. isAttr: true,
  15560. type: "String"
  15561. }
  15562. ]
  15563. },
  15564. {
  15565. name: "ImplicitThrowEvent",
  15566. superClass: [
  15567. "ThrowEvent"
  15568. ]
  15569. },
  15570. {
  15571. name: "DataState",
  15572. superClass: [
  15573. "BaseElement"
  15574. ],
  15575. properties: [
  15576. {
  15577. name: "name",
  15578. isAttr: true,
  15579. type: "String"
  15580. }
  15581. ]
  15582. },
  15583. {
  15584. name: "ItemAwareElement",
  15585. superClass: [
  15586. "BaseElement"
  15587. ],
  15588. properties: [
  15589. {
  15590. name: "itemSubjectRef",
  15591. type: "ItemDefinition",
  15592. isAttr: true,
  15593. isReference: true
  15594. },
  15595. {
  15596. name: "dataState",
  15597. type: "DataState"
  15598. }
  15599. ]
  15600. },
  15601. {
  15602. name: "DataAssociation",
  15603. superClass: [
  15604. "BaseElement"
  15605. ],
  15606. properties: [
  15607. {
  15608. name: "sourceRef",
  15609. type: "ItemAwareElement",
  15610. isMany: true,
  15611. isReference: true
  15612. },
  15613. {
  15614. name: "targetRef",
  15615. type: "ItemAwareElement",
  15616. isReference: true
  15617. },
  15618. {
  15619. name: "transformation",
  15620. type: "FormalExpression",
  15621. xml: {
  15622. serialize: "property"
  15623. }
  15624. },
  15625. {
  15626. name: "assignment",
  15627. type: "Assignment",
  15628. isMany: true
  15629. }
  15630. ]
  15631. },
  15632. {
  15633. name: "DataInput",
  15634. superClass: [
  15635. "ItemAwareElement"
  15636. ],
  15637. properties: [
  15638. {
  15639. name: "name",
  15640. isAttr: true,
  15641. type: "String"
  15642. },
  15643. {
  15644. name: "isCollection",
  15645. "default": false,
  15646. isAttr: true,
  15647. type: "Boolean"
  15648. },
  15649. {
  15650. name: "inputSetRef",
  15651. type: "InputSet",
  15652. isMany: true,
  15653. isVirtual: true,
  15654. isReference: true
  15655. },
  15656. {
  15657. name: "inputSetWithOptional",
  15658. type: "InputSet",
  15659. isMany: true,
  15660. isVirtual: true,
  15661. isReference: true
  15662. },
  15663. {
  15664. name: "inputSetWithWhileExecuting",
  15665. type: "InputSet",
  15666. isMany: true,
  15667. isVirtual: true,
  15668. isReference: true
  15669. }
  15670. ]
  15671. },
  15672. {
  15673. name: "DataOutput",
  15674. superClass: [
  15675. "ItemAwareElement"
  15676. ],
  15677. properties: [
  15678. {
  15679. name: "name",
  15680. isAttr: true,
  15681. type: "String"
  15682. },
  15683. {
  15684. name: "isCollection",
  15685. "default": false,
  15686. isAttr: true,
  15687. type: "Boolean"
  15688. },
  15689. {
  15690. name: "outputSetRef",
  15691. type: "OutputSet",
  15692. isMany: true,
  15693. isVirtual: true,
  15694. isReference: true
  15695. },
  15696. {
  15697. name: "outputSetWithOptional",
  15698. type: "OutputSet",
  15699. isMany: true,
  15700. isVirtual: true,
  15701. isReference: true
  15702. },
  15703. {
  15704. name: "outputSetWithWhileExecuting",
  15705. type: "OutputSet",
  15706. isMany: true,
  15707. isVirtual: true,
  15708. isReference: true
  15709. }
  15710. ]
  15711. },
  15712. {
  15713. name: "InputSet",
  15714. superClass: [
  15715. "BaseElement"
  15716. ],
  15717. properties: [
  15718. {
  15719. name: "name",
  15720. isAttr: true,
  15721. type: "String"
  15722. },
  15723. {
  15724. name: "dataInputRefs",
  15725. type: "DataInput",
  15726. isMany: true,
  15727. isReference: true
  15728. },
  15729. {
  15730. name: "optionalInputRefs",
  15731. type: "DataInput",
  15732. isMany: true,
  15733. isReference: true
  15734. },
  15735. {
  15736. name: "whileExecutingInputRefs",
  15737. type: "DataInput",
  15738. isMany: true,
  15739. isReference: true
  15740. },
  15741. {
  15742. name: "outputSetRefs",
  15743. type: "OutputSet",
  15744. isMany: true,
  15745. isReference: true
  15746. }
  15747. ]
  15748. },
  15749. {
  15750. name: "OutputSet",
  15751. superClass: [
  15752. "BaseElement"
  15753. ],
  15754. properties: [
  15755. {
  15756. name: "dataOutputRefs",
  15757. type: "DataOutput",
  15758. isMany: true,
  15759. isReference: true
  15760. },
  15761. {
  15762. name: "name",
  15763. isAttr: true,
  15764. type: "String"
  15765. },
  15766. {
  15767. name: "inputSetRefs",
  15768. type: "InputSet",
  15769. isMany: true,
  15770. isReference: true
  15771. },
  15772. {
  15773. name: "optionalOutputRefs",
  15774. type: "DataOutput",
  15775. isMany: true,
  15776. isReference: true
  15777. },
  15778. {
  15779. name: "whileExecutingOutputRefs",
  15780. type: "DataOutput",
  15781. isMany: true,
  15782. isReference: true
  15783. }
  15784. ]
  15785. },
  15786. {
  15787. name: "Property",
  15788. superClass: [
  15789. "ItemAwareElement"
  15790. ],
  15791. properties: [
  15792. {
  15793. name: "name",
  15794. isAttr: true,
  15795. type: "String"
  15796. }
  15797. ]
  15798. },
  15799. {
  15800. name: "DataInputAssociation",
  15801. superClass: [
  15802. "DataAssociation"
  15803. ]
  15804. },
  15805. {
  15806. name: "DataOutputAssociation",
  15807. superClass: [
  15808. "DataAssociation"
  15809. ]
  15810. },
  15811. {
  15812. name: "InputOutputSpecification",
  15813. superClass: [
  15814. "BaseElement"
  15815. ],
  15816. properties: [
  15817. {
  15818. name: "dataInputs",
  15819. type: "DataInput",
  15820. isMany: true
  15821. },
  15822. {
  15823. name: "dataOutputs",
  15824. type: "DataOutput",
  15825. isMany: true
  15826. },
  15827. {
  15828. name: "inputSets",
  15829. type: "InputSet",
  15830. isMany: true
  15831. },
  15832. {
  15833. name: "outputSets",
  15834. type: "OutputSet",
  15835. isMany: true
  15836. }
  15837. ]
  15838. },
  15839. {
  15840. name: "DataObject",
  15841. superClass: [
  15842. "FlowElement",
  15843. "ItemAwareElement"
  15844. ],
  15845. properties: [
  15846. {
  15847. name: "isCollection",
  15848. "default": false,
  15849. isAttr: true,
  15850. type: "Boolean"
  15851. }
  15852. ]
  15853. },
  15854. {
  15855. name: "InputOutputBinding",
  15856. properties: [
  15857. {
  15858. name: "inputDataRef",
  15859. type: "InputSet",
  15860. isAttr: true,
  15861. isReference: true
  15862. },
  15863. {
  15864. name: "outputDataRef",
  15865. type: "OutputSet",
  15866. isAttr: true,
  15867. isReference: true
  15868. },
  15869. {
  15870. name: "operationRef",
  15871. type: "Operation",
  15872. isAttr: true,
  15873. isReference: true
  15874. }
  15875. ]
  15876. },
  15877. {
  15878. name: "Assignment",
  15879. superClass: [
  15880. "BaseElement"
  15881. ],
  15882. properties: [
  15883. {
  15884. name: "from",
  15885. type: "Expression",
  15886. xml: {
  15887. serialize: "xsi:type"
  15888. }
  15889. },
  15890. {
  15891. name: "to",
  15892. type: "Expression",
  15893. xml: {
  15894. serialize: "xsi:type"
  15895. }
  15896. }
  15897. ]
  15898. },
  15899. {
  15900. name: "DataStore",
  15901. superClass: [
  15902. "RootElement",
  15903. "ItemAwareElement"
  15904. ],
  15905. properties: [
  15906. {
  15907. name: "name",
  15908. isAttr: true,
  15909. type: "String"
  15910. },
  15911. {
  15912. name: "capacity",
  15913. isAttr: true,
  15914. type: "Integer"
  15915. },
  15916. {
  15917. name: "isUnlimited",
  15918. "default": true,
  15919. isAttr: true,
  15920. type: "Boolean"
  15921. }
  15922. ]
  15923. },
  15924. {
  15925. name: "DataStoreReference",
  15926. superClass: [
  15927. "ItemAwareElement",
  15928. "FlowElement"
  15929. ],
  15930. properties: [
  15931. {
  15932. name: "dataStoreRef",
  15933. type: "DataStore",
  15934. isAttr: true,
  15935. isReference: true
  15936. }
  15937. ]
  15938. },
  15939. {
  15940. name: "DataObjectReference",
  15941. superClass: [
  15942. "ItemAwareElement",
  15943. "FlowElement"
  15944. ],
  15945. properties: [
  15946. {
  15947. name: "dataObjectRef",
  15948. type: "DataObject",
  15949. isAttr: true,
  15950. isReference: true
  15951. }
  15952. ]
  15953. },
  15954. {
  15955. name: "ConversationLink",
  15956. superClass: [
  15957. "BaseElement"
  15958. ],
  15959. properties: [
  15960. {
  15961. name: "sourceRef",
  15962. type: "InteractionNode",
  15963. isAttr: true,
  15964. isReference: true
  15965. },
  15966. {
  15967. name: "targetRef",
  15968. type: "InteractionNode",
  15969. isAttr: true,
  15970. isReference: true
  15971. },
  15972. {
  15973. name: "name",
  15974. isAttr: true,
  15975. type: "String"
  15976. }
  15977. ]
  15978. },
  15979. {
  15980. name: "ConversationAssociation",
  15981. superClass: [
  15982. "BaseElement"
  15983. ],
  15984. properties: [
  15985. {
  15986. name: "innerConversationNodeRef",
  15987. type: "ConversationNode",
  15988. isAttr: true,
  15989. isReference: true
  15990. },
  15991. {
  15992. name: "outerConversationNodeRef",
  15993. type: "ConversationNode",
  15994. isAttr: true,
  15995. isReference: true
  15996. }
  15997. ]
  15998. },
  15999. {
  16000. name: "CallConversation",
  16001. superClass: [
  16002. "ConversationNode"
  16003. ],
  16004. properties: [
  16005. {
  16006. name: "calledCollaborationRef",
  16007. type: "Collaboration",
  16008. isAttr: true,
  16009. isReference: true
  16010. },
  16011. {
  16012. name: "participantAssociations",
  16013. type: "ParticipantAssociation",
  16014. isMany: true
  16015. }
  16016. ]
  16017. },
  16018. {
  16019. name: "Conversation",
  16020. superClass: [
  16021. "ConversationNode"
  16022. ]
  16023. },
  16024. {
  16025. name: "SubConversation",
  16026. superClass: [
  16027. "ConversationNode"
  16028. ],
  16029. properties: [
  16030. {
  16031. name: "conversationNodes",
  16032. type: "ConversationNode",
  16033. isMany: true
  16034. }
  16035. ]
  16036. },
  16037. {
  16038. name: "ConversationNode",
  16039. isAbstract: true,
  16040. superClass: [
  16041. "InteractionNode",
  16042. "BaseElement"
  16043. ],
  16044. properties: [
  16045. {
  16046. name: "name",
  16047. isAttr: true,
  16048. type: "String"
  16049. },
  16050. {
  16051. name: "participantRef",
  16052. type: "Participant",
  16053. isMany: true,
  16054. isReference: true
  16055. },
  16056. {
  16057. name: "messageFlowRefs",
  16058. type: "MessageFlow",
  16059. isMany: true,
  16060. isReference: true
  16061. },
  16062. {
  16063. name: "correlationKeys",
  16064. type: "CorrelationKey",
  16065. isMany: true
  16066. }
  16067. ]
  16068. },
  16069. {
  16070. name: "GlobalConversation",
  16071. superClass: [
  16072. "Collaboration"
  16073. ]
  16074. },
  16075. {
  16076. name: "PartnerEntity",
  16077. superClass: [
  16078. "RootElement"
  16079. ],
  16080. properties: [
  16081. {
  16082. name: "name",
  16083. isAttr: true,
  16084. type: "String"
  16085. },
  16086. {
  16087. name: "participantRef",
  16088. type: "Participant",
  16089. isMany: true,
  16090. isReference: true
  16091. }
  16092. ]
  16093. },
  16094. {
  16095. name: "PartnerRole",
  16096. superClass: [
  16097. "RootElement"
  16098. ],
  16099. properties: [
  16100. {
  16101. name: "name",
  16102. isAttr: true,
  16103. type: "String"
  16104. },
  16105. {
  16106. name: "participantRef",
  16107. type: "Participant",
  16108. isMany: true,
  16109. isReference: true
  16110. }
  16111. ]
  16112. },
  16113. {
  16114. name: "CorrelationProperty",
  16115. superClass: [
  16116. "RootElement"
  16117. ],
  16118. properties: [
  16119. {
  16120. name: "correlationPropertyRetrievalExpression",
  16121. type: "CorrelationPropertyRetrievalExpression",
  16122. isMany: true
  16123. },
  16124. {
  16125. name: "name",
  16126. isAttr: true,
  16127. type: "String"
  16128. },
  16129. {
  16130. name: "type",
  16131. type: "ItemDefinition",
  16132. isAttr: true,
  16133. isReference: true
  16134. }
  16135. ]
  16136. },
  16137. {
  16138. name: "Error",
  16139. superClass: [
  16140. "RootElement"
  16141. ],
  16142. properties: [
  16143. {
  16144. name: "structureRef",
  16145. type: "ItemDefinition",
  16146. isAttr: true,
  16147. isReference: true
  16148. },
  16149. {
  16150. name: "name",
  16151. isAttr: true,
  16152. type: "String"
  16153. },
  16154. {
  16155. name: "errorCode",
  16156. isAttr: true,
  16157. type: "String"
  16158. }
  16159. ]
  16160. },
  16161. {
  16162. name: "CorrelationKey",
  16163. superClass: [
  16164. "BaseElement"
  16165. ],
  16166. properties: [
  16167. {
  16168. name: "correlationPropertyRef",
  16169. type: "CorrelationProperty",
  16170. isMany: true,
  16171. isReference: true
  16172. },
  16173. {
  16174. name: "name",
  16175. isAttr: true,
  16176. type: "String"
  16177. }
  16178. ]
  16179. },
  16180. {
  16181. name: "Expression",
  16182. superClass: [
  16183. "BaseElement"
  16184. ],
  16185. isAbstract: false,
  16186. properties: [
  16187. {
  16188. name: "body",
  16189. isBody: true,
  16190. type: "String"
  16191. }
  16192. ]
  16193. },
  16194. {
  16195. name: "FormalExpression",
  16196. superClass: [
  16197. "Expression"
  16198. ],
  16199. properties: [
  16200. {
  16201. name: "language",
  16202. isAttr: true,
  16203. type: "String"
  16204. },
  16205. {
  16206. name: "evaluatesToTypeRef",
  16207. type: "ItemDefinition",
  16208. isAttr: true,
  16209. isReference: true
  16210. }
  16211. ]
  16212. },
  16213. {
  16214. name: "Message",
  16215. superClass: [
  16216. "RootElement"
  16217. ],
  16218. properties: [
  16219. {
  16220. name: "name",
  16221. isAttr: true,
  16222. type: "String"
  16223. },
  16224. {
  16225. name: "itemRef",
  16226. type: "ItemDefinition",
  16227. isAttr: true,
  16228. isReference: true
  16229. }
  16230. ]
  16231. },
  16232. {
  16233. name: "ItemDefinition",
  16234. superClass: [
  16235. "RootElement"
  16236. ],
  16237. properties: [
  16238. {
  16239. name: "itemKind",
  16240. type: "ItemKind",
  16241. isAttr: true
  16242. },
  16243. {
  16244. name: "structureRef",
  16245. isAttr: true,
  16246. type: "String"
  16247. },
  16248. {
  16249. name: "isCollection",
  16250. "default": false,
  16251. isAttr: true,
  16252. type: "Boolean"
  16253. },
  16254. {
  16255. name: "import",
  16256. type: "Import",
  16257. isAttr: true,
  16258. isReference: true
  16259. }
  16260. ]
  16261. },
  16262. {
  16263. name: "FlowElement",
  16264. isAbstract: true,
  16265. superClass: [
  16266. "BaseElement"
  16267. ],
  16268. properties: [
  16269. {
  16270. name: "name",
  16271. isAttr: true,
  16272. type: "String"
  16273. },
  16274. {
  16275. name: "auditing",
  16276. type: "Auditing"
  16277. },
  16278. {
  16279. name: "monitoring",
  16280. type: "Monitoring"
  16281. },
  16282. {
  16283. name: "categoryValueRef",
  16284. type: "CategoryValue",
  16285. isMany: true,
  16286. isReference: true
  16287. }
  16288. ]
  16289. },
  16290. {
  16291. name: "SequenceFlow",
  16292. superClass: [
  16293. "FlowElement"
  16294. ],
  16295. properties: [
  16296. {
  16297. name: "isImmediate",
  16298. isAttr: true,
  16299. type: "Boolean"
  16300. },
  16301. {
  16302. name: "conditionExpression",
  16303. type: "Expression",
  16304. xml: {
  16305. serialize: "xsi:type"
  16306. }
  16307. },
  16308. {
  16309. name: "sourceRef",
  16310. type: "FlowNode",
  16311. isAttr: true,
  16312. isReference: true
  16313. },
  16314. {
  16315. name: "targetRef",
  16316. type: "FlowNode",
  16317. isAttr: true,
  16318. isReference: true
  16319. }
  16320. ]
  16321. },
  16322. {
  16323. name: "FlowElementsContainer",
  16324. isAbstract: true,
  16325. superClass: [
  16326. "BaseElement"
  16327. ],
  16328. properties: [
  16329. {
  16330. name: "laneSets",
  16331. type: "LaneSet",
  16332. isMany: true
  16333. },
  16334. {
  16335. name: "flowElements",
  16336. type: "FlowElement",
  16337. isMany: true
  16338. }
  16339. ]
  16340. },
  16341. {
  16342. name: "CallableElement",
  16343. isAbstract: true,
  16344. superClass: [
  16345. "RootElement"
  16346. ],
  16347. properties: [
  16348. {
  16349. name: "name",
  16350. isAttr: true,
  16351. type: "String"
  16352. },
  16353. {
  16354. name: "ioSpecification",
  16355. type: "InputOutputSpecification",
  16356. xml: {
  16357. serialize: "property"
  16358. }
  16359. },
  16360. {
  16361. name: "supportedInterfaceRef",
  16362. type: "Interface",
  16363. isMany: true,
  16364. isReference: true
  16365. },
  16366. {
  16367. name: "ioBinding",
  16368. type: "InputOutputBinding",
  16369. isMany: true,
  16370. xml: {
  16371. serialize: "property"
  16372. }
  16373. }
  16374. ]
  16375. },
  16376. {
  16377. name: "FlowNode",
  16378. isAbstract: true,
  16379. superClass: [
  16380. "FlowElement"
  16381. ],
  16382. properties: [
  16383. {
  16384. name: "incoming",
  16385. type: "SequenceFlow",
  16386. isMany: true,
  16387. isReference: true
  16388. },
  16389. {
  16390. name: "outgoing",
  16391. type: "SequenceFlow",
  16392. isMany: true,
  16393. isReference: true
  16394. },
  16395. {
  16396. name: "lanes",
  16397. type: "Lane",
  16398. isMany: true,
  16399. isVirtual: true,
  16400. isReference: true
  16401. }
  16402. ]
  16403. },
  16404. {
  16405. name: "CorrelationPropertyRetrievalExpression",
  16406. superClass: [
  16407. "BaseElement"
  16408. ],
  16409. properties: [
  16410. {
  16411. name: "messagePath",
  16412. type: "FormalExpression"
  16413. },
  16414. {
  16415. name: "messageRef",
  16416. type: "Message",
  16417. isAttr: true,
  16418. isReference: true
  16419. }
  16420. ]
  16421. },
  16422. {
  16423. name: "CorrelationPropertyBinding",
  16424. superClass: [
  16425. "BaseElement"
  16426. ],
  16427. properties: [
  16428. {
  16429. name: "dataPath",
  16430. type: "FormalExpression"
  16431. },
  16432. {
  16433. name: "correlationPropertyRef",
  16434. type: "CorrelationProperty",
  16435. isAttr: true,
  16436. isReference: true
  16437. }
  16438. ]
  16439. },
  16440. {
  16441. name: "Resource",
  16442. superClass: [
  16443. "RootElement"
  16444. ],
  16445. properties: [
  16446. {
  16447. name: "name",
  16448. isAttr: true,
  16449. type: "String"
  16450. },
  16451. {
  16452. name: "resourceParameters",
  16453. type: "ResourceParameter",
  16454. isMany: true
  16455. }
  16456. ]
  16457. },
  16458. {
  16459. name: "ResourceParameter",
  16460. superClass: [
  16461. "BaseElement"
  16462. ],
  16463. properties: [
  16464. {
  16465. name: "name",
  16466. isAttr: true,
  16467. type: "String"
  16468. },
  16469. {
  16470. name: "isRequired",
  16471. isAttr: true,
  16472. type: "Boolean"
  16473. },
  16474. {
  16475. name: "type",
  16476. type: "ItemDefinition",
  16477. isAttr: true,
  16478. isReference: true
  16479. }
  16480. ]
  16481. },
  16482. {
  16483. name: "CorrelationSubscription",
  16484. superClass: [
  16485. "BaseElement"
  16486. ],
  16487. properties: [
  16488. {
  16489. name: "correlationKeyRef",
  16490. type: "CorrelationKey",
  16491. isAttr: true,
  16492. isReference: true
  16493. },
  16494. {
  16495. name: "correlationPropertyBinding",
  16496. type: "CorrelationPropertyBinding",
  16497. isMany: true
  16498. }
  16499. ]
  16500. },
  16501. {
  16502. name: "MessageFlow",
  16503. superClass: [
  16504. "BaseElement"
  16505. ],
  16506. properties: [
  16507. {
  16508. name: "name",
  16509. isAttr: true,
  16510. type: "String"
  16511. },
  16512. {
  16513. name: "sourceRef",
  16514. type: "InteractionNode",
  16515. isAttr: true,
  16516. isReference: true
  16517. },
  16518. {
  16519. name: "targetRef",
  16520. type: "InteractionNode",
  16521. isAttr: true,
  16522. isReference: true
  16523. },
  16524. {
  16525. name: "messageRef",
  16526. type: "Message",
  16527. isAttr: true,
  16528. isReference: true
  16529. }
  16530. ]
  16531. },
  16532. {
  16533. name: "MessageFlowAssociation",
  16534. superClass: [
  16535. "BaseElement"
  16536. ],
  16537. properties: [
  16538. {
  16539. name: "innerMessageFlowRef",
  16540. type: "MessageFlow",
  16541. isAttr: true,
  16542. isReference: true
  16543. },
  16544. {
  16545. name: "outerMessageFlowRef",
  16546. type: "MessageFlow",
  16547. isAttr: true,
  16548. isReference: true
  16549. }
  16550. ]
  16551. },
  16552. {
  16553. name: "InteractionNode",
  16554. isAbstract: true,
  16555. properties: [
  16556. {
  16557. name: "incomingConversationLinks",
  16558. type: "ConversationLink",
  16559. isMany: true,
  16560. isVirtual: true,
  16561. isReference: true
  16562. },
  16563. {
  16564. name: "outgoingConversationLinks",
  16565. type: "ConversationLink",
  16566. isMany: true,
  16567. isVirtual: true,
  16568. isReference: true
  16569. }
  16570. ]
  16571. },
  16572. {
  16573. name: "Participant",
  16574. superClass: [
  16575. "InteractionNode",
  16576. "BaseElement"
  16577. ],
  16578. properties: [
  16579. {
  16580. name: "name",
  16581. isAttr: true,
  16582. type: "String"
  16583. },
  16584. {
  16585. name: "interfaceRef",
  16586. type: "Interface",
  16587. isMany: true,
  16588. isReference: true
  16589. },
  16590. {
  16591. name: "participantMultiplicity",
  16592. type: "ParticipantMultiplicity"
  16593. },
  16594. {
  16595. name: "endPointRefs",
  16596. type: "EndPoint",
  16597. isMany: true,
  16598. isReference: true
  16599. },
  16600. {
  16601. name: "processRef",
  16602. type: "Process",
  16603. isAttr: true,
  16604. isReference: true
  16605. }
  16606. ]
  16607. },
  16608. {
  16609. name: "ParticipantAssociation",
  16610. superClass: [
  16611. "BaseElement"
  16612. ],
  16613. properties: [
  16614. {
  16615. name: "innerParticipantRef",
  16616. type: "Participant",
  16617. isAttr: true,
  16618. isReference: true
  16619. },
  16620. {
  16621. name: "outerParticipantRef",
  16622. type: "Participant",
  16623. isAttr: true,
  16624. isReference: true
  16625. }
  16626. ]
  16627. },
  16628. {
  16629. name: "ParticipantMultiplicity",
  16630. properties: [
  16631. {
  16632. name: "minimum",
  16633. "default": 0,
  16634. isAttr: true,
  16635. type: "Integer"
  16636. },
  16637. {
  16638. name: "maximum",
  16639. "default": 1,
  16640. isAttr: true,
  16641. type: "Integer"
  16642. }
  16643. ],
  16644. superClass: [
  16645. "BaseElement"
  16646. ]
  16647. },
  16648. {
  16649. name: "Collaboration",
  16650. superClass: [
  16651. "RootElement"
  16652. ],
  16653. properties: [
  16654. {
  16655. name: "name",
  16656. isAttr: true,
  16657. type: "String"
  16658. },
  16659. {
  16660. name: "isClosed",
  16661. isAttr: true,
  16662. type: "Boolean"
  16663. },
  16664. {
  16665. name: "participants",
  16666. type: "Participant",
  16667. isMany: true
  16668. },
  16669. {
  16670. name: "messageFlows",
  16671. type: "MessageFlow",
  16672. isMany: true
  16673. },
  16674. {
  16675. name: "artifacts",
  16676. type: "Artifact",
  16677. isMany: true
  16678. },
  16679. {
  16680. name: "conversations",
  16681. type: "ConversationNode",
  16682. isMany: true
  16683. },
  16684. {
  16685. name: "conversationAssociations",
  16686. type: "ConversationAssociation"
  16687. },
  16688. {
  16689. name: "participantAssociations",
  16690. type: "ParticipantAssociation",
  16691. isMany: true
  16692. },
  16693. {
  16694. name: "messageFlowAssociations",
  16695. type: "MessageFlowAssociation",
  16696. isMany: true
  16697. },
  16698. {
  16699. name: "correlationKeys",
  16700. type: "CorrelationKey",
  16701. isMany: true
  16702. },
  16703. {
  16704. name: "choreographyRef",
  16705. type: "Choreography",
  16706. isMany: true,
  16707. isReference: true
  16708. },
  16709. {
  16710. name: "conversationLinks",
  16711. type: "ConversationLink",
  16712. isMany: true
  16713. }
  16714. ]
  16715. },
  16716. {
  16717. name: "ChoreographyActivity",
  16718. isAbstract: true,
  16719. superClass: [
  16720. "FlowNode"
  16721. ],
  16722. properties: [
  16723. {
  16724. name: "participantRef",
  16725. type: "Participant",
  16726. isMany: true,
  16727. isReference: true
  16728. },
  16729. {
  16730. name: "initiatingParticipantRef",
  16731. type: "Participant",
  16732. isAttr: true,
  16733. isReference: true
  16734. },
  16735. {
  16736. name: "correlationKeys",
  16737. type: "CorrelationKey",
  16738. isMany: true
  16739. },
  16740. {
  16741. name: "loopType",
  16742. type: "ChoreographyLoopType",
  16743. "default": "None",
  16744. isAttr: true
  16745. }
  16746. ]
  16747. },
  16748. {
  16749. name: "CallChoreography",
  16750. superClass: [
  16751. "ChoreographyActivity"
  16752. ],
  16753. properties: [
  16754. {
  16755. name: "calledChoreographyRef",
  16756. type: "Choreography",
  16757. isAttr: true,
  16758. isReference: true
  16759. },
  16760. {
  16761. name: "participantAssociations",
  16762. type: "ParticipantAssociation",
  16763. isMany: true
  16764. }
  16765. ]
  16766. },
  16767. {
  16768. name: "SubChoreography",
  16769. superClass: [
  16770. "ChoreographyActivity",
  16771. "FlowElementsContainer"
  16772. ],
  16773. properties: [
  16774. {
  16775. name: "artifacts",
  16776. type: "Artifact",
  16777. isMany: true
  16778. }
  16779. ]
  16780. },
  16781. {
  16782. name: "ChoreographyTask",
  16783. superClass: [
  16784. "ChoreographyActivity"
  16785. ],
  16786. properties: [
  16787. {
  16788. name: "messageFlowRef",
  16789. type: "MessageFlow",
  16790. isMany: true,
  16791. isReference: true
  16792. }
  16793. ]
  16794. },
  16795. {
  16796. name: "Choreography",
  16797. superClass: [
  16798. "Collaboration",
  16799. "FlowElementsContainer"
  16800. ]
  16801. },
  16802. {
  16803. name: "GlobalChoreographyTask",
  16804. superClass: [
  16805. "Choreography"
  16806. ],
  16807. properties: [
  16808. {
  16809. name: "initiatingParticipantRef",
  16810. type: "Participant",
  16811. isAttr: true,
  16812. isReference: true
  16813. }
  16814. ]
  16815. },
  16816. {
  16817. name: "TextAnnotation",
  16818. superClass: [
  16819. "Artifact"
  16820. ],
  16821. properties: [
  16822. {
  16823. name: "text",
  16824. type: "String"
  16825. },
  16826. {
  16827. name: "textFormat",
  16828. "default": "text/plain",
  16829. isAttr: true,
  16830. type: "String"
  16831. }
  16832. ]
  16833. },
  16834. {
  16835. name: "Group",
  16836. superClass: [
  16837. "Artifact"
  16838. ],
  16839. properties: [
  16840. {
  16841. name: "categoryValueRef",
  16842. type: "CategoryValue",
  16843. isAttr: true,
  16844. isReference: true
  16845. }
  16846. ]
  16847. },
  16848. {
  16849. name: "Association",
  16850. superClass: [
  16851. "Artifact"
  16852. ],
  16853. properties: [
  16854. {
  16855. name: "associationDirection",
  16856. type: "AssociationDirection",
  16857. isAttr: true
  16858. },
  16859. {
  16860. name: "sourceRef",
  16861. type: "BaseElement",
  16862. isAttr: true,
  16863. isReference: true
  16864. },
  16865. {
  16866. name: "targetRef",
  16867. type: "BaseElement",
  16868. isAttr: true,
  16869. isReference: true
  16870. }
  16871. ]
  16872. },
  16873. {
  16874. name: "Category",
  16875. superClass: [
  16876. "RootElement"
  16877. ],
  16878. properties: [
  16879. {
  16880. name: "categoryValue",
  16881. type: "CategoryValue",
  16882. isMany: true
  16883. },
  16884. {
  16885. name: "name",
  16886. isAttr: true,
  16887. type: "String"
  16888. }
  16889. ]
  16890. },
  16891. {
  16892. name: "Artifact",
  16893. isAbstract: true,
  16894. superClass: [
  16895. "BaseElement"
  16896. ]
  16897. },
  16898. {
  16899. name: "CategoryValue",
  16900. superClass: [
  16901. "BaseElement"
  16902. ],
  16903. properties: [
  16904. {
  16905. name: "categorizedFlowElements",
  16906. type: "FlowElement",
  16907. isMany: true,
  16908. isVirtual: true,
  16909. isReference: true
  16910. },
  16911. {
  16912. name: "value",
  16913. isAttr: true,
  16914. type: "String"
  16915. }
  16916. ]
  16917. },
  16918. {
  16919. name: "Activity",
  16920. isAbstract: true,
  16921. superClass: [
  16922. "FlowNode"
  16923. ],
  16924. properties: [
  16925. {
  16926. name: "isForCompensation",
  16927. "default": false,
  16928. isAttr: true,
  16929. type: "Boolean"
  16930. },
  16931. {
  16932. name: "default",
  16933. type: "SequenceFlow",
  16934. isAttr: true,
  16935. isReference: true
  16936. },
  16937. {
  16938. name: "ioSpecification",
  16939. type: "InputOutputSpecification",
  16940. xml: {
  16941. serialize: "property"
  16942. }
  16943. },
  16944. {
  16945. name: "boundaryEventRefs",
  16946. type: "BoundaryEvent",
  16947. isMany: true,
  16948. isReference: true
  16949. },
  16950. {
  16951. name: "properties",
  16952. type: "Property",
  16953. isMany: true
  16954. },
  16955. {
  16956. name: "dataInputAssociations",
  16957. type: "DataInputAssociation",
  16958. isMany: true
  16959. },
  16960. {
  16961. name: "dataOutputAssociations",
  16962. type: "DataOutputAssociation",
  16963. isMany: true
  16964. },
  16965. {
  16966. name: "startQuantity",
  16967. "default": 1,
  16968. isAttr: true,
  16969. type: "Integer"
  16970. },
  16971. {
  16972. name: "resources",
  16973. type: "ResourceRole",
  16974. isMany: true
  16975. },
  16976. {
  16977. name: "completionQuantity",
  16978. "default": 1,
  16979. isAttr: true,
  16980. type: "Integer"
  16981. },
  16982. {
  16983. name: "loopCharacteristics",
  16984. type: "LoopCharacteristics"
  16985. }
  16986. ]
  16987. },
  16988. {
  16989. name: "ServiceTask",
  16990. superClass: [
  16991. "Task"
  16992. ],
  16993. properties: [
  16994. {
  16995. name: "implementation",
  16996. isAttr: true,
  16997. type: "String"
  16998. },
  16999. {
  17000. name: "operationRef",
  17001. type: "Operation",
  17002. isAttr: true,
  17003. isReference: true
  17004. }
  17005. ]
  17006. },
  17007. {
  17008. name: "SubProcess",
  17009. superClass: [
  17010. "Activity",
  17011. "FlowElementsContainer",
  17012. "InteractionNode"
  17013. ],
  17014. properties: [
  17015. {
  17016. name: "triggeredByEvent",
  17017. "default": false,
  17018. isAttr: true,
  17019. type: "Boolean"
  17020. },
  17021. {
  17022. name: "artifacts",
  17023. type: "Artifact",
  17024. isMany: true
  17025. }
  17026. ]
  17027. },
  17028. {
  17029. name: "LoopCharacteristics",
  17030. isAbstract: true,
  17031. superClass: [
  17032. "BaseElement"
  17033. ]
  17034. },
  17035. {
  17036. name: "MultiInstanceLoopCharacteristics",
  17037. superClass: [
  17038. "LoopCharacteristics"
  17039. ],
  17040. properties: [
  17041. {
  17042. name: "isSequential",
  17043. "default": false,
  17044. isAttr: true,
  17045. type: "Boolean"
  17046. },
  17047. {
  17048. name: "behavior",
  17049. type: "MultiInstanceBehavior",
  17050. "default": "All",
  17051. isAttr: true
  17052. },
  17053. {
  17054. name: "loopCardinality",
  17055. type: "Expression",
  17056. xml: {
  17057. serialize: "xsi:type"
  17058. }
  17059. },
  17060. {
  17061. name: "loopDataInputRef",
  17062. type: "ItemAwareElement",
  17063. isReference: true
  17064. },
  17065. {
  17066. name: "loopDataOutputRef",
  17067. type: "ItemAwareElement",
  17068. isReference: true
  17069. },
  17070. {
  17071. name: "inputDataItem",
  17072. type: "DataInput",
  17073. xml: {
  17074. serialize: "property"
  17075. }
  17076. },
  17077. {
  17078. name: "outputDataItem",
  17079. type: "DataOutput",
  17080. xml: {
  17081. serialize: "property"
  17082. }
  17083. },
  17084. {
  17085. name: "complexBehaviorDefinition",
  17086. type: "ComplexBehaviorDefinition",
  17087. isMany: true
  17088. },
  17089. {
  17090. name: "completionCondition",
  17091. type: "Expression",
  17092. xml: {
  17093. serialize: "xsi:type"
  17094. }
  17095. },
  17096. {
  17097. name: "oneBehaviorEventRef",
  17098. type: "EventDefinition",
  17099. isAttr: true,
  17100. isReference: true
  17101. },
  17102. {
  17103. name: "noneBehaviorEventRef",
  17104. type: "EventDefinition",
  17105. isAttr: true,
  17106. isReference: true
  17107. }
  17108. ]
  17109. },
  17110. {
  17111. name: "StandardLoopCharacteristics",
  17112. superClass: [
  17113. "LoopCharacteristics"
  17114. ],
  17115. properties: [
  17116. {
  17117. name: "testBefore",
  17118. "default": false,
  17119. isAttr: true,
  17120. type: "Boolean"
  17121. },
  17122. {
  17123. name: "loopCondition",
  17124. type: "Expression",
  17125. xml: {
  17126. serialize: "xsi:type"
  17127. }
  17128. },
  17129. {
  17130. name: "loopMaximum",
  17131. type: "Integer",
  17132. isAttr: true
  17133. }
  17134. ]
  17135. },
  17136. {
  17137. name: "CallActivity",
  17138. superClass: [
  17139. "Activity",
  17140. "InteractionNode"
  17141. ],
  17142. properties: [
  17143. {
  17144. name: "calledElement",
  17145. type: "String",
  17146. isAttr: true
  17147. }
  17148. ]
  17149. },
  17150. {
  17151. name: "Task",
  17152. superClass: [
  17153. "Activity",
  17154. "InteractionNode"
  17155. ]
  17156. },
  17157. {
  17158. name: "SendTask",
  17159. superClass: [
  17160. "Task"
  17161. ],
  17162. properties: [
  17163. {
  17164. name: "implementation",
  17165. isAttr: true,
  17166. type: "String"
  17167. },
  17168. {
  17169. name: "operationRef",
  17170. type: "Operation",
  17171. isAttr: true,
  17172. isReference: true
  17173. },
  17174. {
  17175. name: "messageRef",
  17176. type: "Message",
  17177. isAttr: true,
  17178. isReference: true
  17179. }
  17180. ]
  17181. },
  17182. {
  17183. name: "ReceiveTask",
  17184. superClass: [
  17185. "Task"
  17186. ],
  17187. properties: [
  17188. {
  17189. name: "implementation",
  17190. isAttr: true,
  17191. type: "String"
  17192. },
  17193. {
  17194. name: "instantiate",
  17195. "default": false,
  17196. isAttr: true,
  17197. type: "Boolean"
  17198. },
  17199. {
  17200. name: "operationRef",
  17201. type: "Operation",
  17202. isAttr: true,
  17203. isReference: true
  17204. },
  17205. {
  17206. name: "messageRef",
  17207. type: "Message",
  17208. isAttr: true,
  17209. isReference: true
  17210. }
  17211. ]
  17212. },
  17213. {
  17214. name: "ScriptTask",
  17215. superClass: [
  17216. "Task"
  17217. ],
  17218. properties: [
  17219. {
  17220. name: "scriptFormat",
  17221. isAttr: true,
  17222. type: "String"
  17223. },
  17224. {
  17225. name: "script",
  17226. type: "String"
  17227. }
  17228. ]
  17229. },
  17230. {
  17231. name: "BusinessRuleTask",
  17232. superClass: [
  17233. "Task"
  17234. ],
  17235. properties: [
  17236. {
  17237. name: "implementation",
  17238. isAttr: true,
  17239. type: "String"
  17240. }
  17241. ]
  17242. },
  17243. {
  17244. name: "AdHocSubProcess",
  17245. superClass: [
  17246. "SubProcess"
  17247. ],
  17248. properties: [
  17249. {
  17250. name: "completionCondition",
  17251. type: "Expression",
  17252. xml: {
  17253. serialize: "xsi:type"
  17254. }
  17255. },
  17256. {
  17257. name: "ordering",
  17258. type: "AdHocOrdering",
  17259. isAttr: true
  17260. },
  17261. {
  17262. name: "cancelRemainingInstances",
  17263. "default": true,
  17264. isAttr: true,
  17265. type: "Boolean"
  17266. }
  17267. ]
  17268. },
  17269. {
  17270. name: "Transaction",
  17271. superClass: [
  17272. "SubProcess"
  17273. ],
  17274. properties: [
  17275. {
  17276. name: "protocol",
  17277. isAttr: true,
  17278. type: "String"
  17279. },
  17280. {
  17281. name: "method",
  17282. isAttr: true,
  17283. type: "String"
  17284. }
  17285. ]
  17286. },
  17287. {
  17288. name: "GlobalScriptTask",
  17289. superClass: [
  17290. "GlobalTask"
  17291. ],
  17292. properties: [
  17293. {
  17294. name: "scriptLanguage",
  17295. isAttr: true,
  17296. type: "String"
  17297. },
  17298. {
  17299. name: "script",
  17300. isAttr: true,
  17301. type: "String"
  17302. }
  17303. ]
  17304. },
  17305. {
  17306. name: "GlobalBusinessRuleTask",
  17307. superClass: [
  17308. "GlobalTask"
  17309. ],
  17310. properties: [
  17311. {
  17312. name: "implementation",
  17313. isAttr: true,
  17314. type: "String"
  17315. }
  17316. ]
  17317. },
  17318. {
  17319. name: "ComplexBehaviorDefinition",
  17320. superClass: [
  17321. "BaseElement"
  17322. ],
  17323. properties: [
  17324. {
  17325. name: "condition",
  17326. type: "FormalExpression"
  17327. },
  17328. {
  17329. name: "event",
  17330. type: "ImplicitThrowEvent"
  17331. }
  17332. ]
  17333. },
  17334. {
  17335. name: "ResourceRole",
  17336. superClass: [
  17337. "BaseElement"
  17338. ],
  17339. properties: [
  17340. {
  17341. name: "resourceRef",
  17342. type: "Resource",
  17343. isReference: true
  17344. },
  17345. {
  17346. name: "resourceParameterBindings",
  17347. type: "ResourceParameterBinding",
  17348. isMany: true
  17349. },
  17350. {
  17351. name: "resourceAssignmentExpression",
  17352. type: "ResourceAssignmentExpression"
  17353. },
  17354. {
  17355. name: "name",
  17356. isAttr: true,
  17357. type: "String"
  17358. }
  17359. ]
  17360. },
  17361. {
  17362. name: "ResourceParameterBinding",
  17363. properties: [
  17364. {
  17365. name: "expression",
  17366. type: "Expression",
  17367. xml: {
  17368. serialize: "xsi:type"
  17369. }
  17370. },
  17371. {
  17372. name: "parameterRef",
  17373. type: "ResourceParameter",
  17374. isAttr: true,
  17375. isReference: true
  17376. }
  17377. ],
  17378. superClass: [
  17379. "BaseElement"
  17380. ]
  17381. },
  17382. {
  17383. name: "ResourceAssignmentExpression",
  17384. properties: [
  17385. {
  17386. name: "expression",
  17387. type: "Expression",
  17388. xml: {
  17389. serialize: "xsi:type"
  17390. }
  17391. }
  17392. ],
  17393. superClass: [
  17394. "BaseElement"
  17395. ]
  17396. },
  17397. {
  17398. name: "Import",
  17399. properties: [
  17400. {
  17401. name: "importType",
  17402. isAttr: true,
  17403. type: "String"
  17404. },
  17405. {
  17406. name: "location",
  17407. isAttr: true,
  17408. type: "String"
  17409. },
  17410. {
  17411. name: "namespace",
  17412. isAttr: true,
  17413. type: "String"
  17414. }
  17415. ]
  17416. },
  17417. {
  17418. name: "Definitions",
  17419. superClass: [
  17420. "BaseElement"
  17421. ],
  17422. properties: [
  17423. {
  17424. name: "name",
  17425. isAttr: true,
  17426. type: "String"
  17427. },
  17428. {
  17429. name: "targetNamespace",
  17430. isAttr: true,
  17431. type: "String"
  17432. },
  17433. {
  17434. name: "expressionLanguage",
  17435. "default": "http://www.w3.org/1999/XPath",
  17436. isAttr: true,
  17437. type: "String"
  17438. },
  17439. {
  17440. name: "typeLanguage",
  17441. "default": "http://www.w3.org/2001/XMLSchema",
  17442. isAttr: true,
  17443. type: "String"
  17444. },
  17445. {
  17446. name: "imports",
  17447. type: "Import",
  17448. isMany: true
  17449. },
  17450. {
  17451. name: "extensions",
  17452. type: "Extension",
  17453. isMany: true
  17454. },
  17455. {
  17456. name: "rootElements",
  17457. type: "RootElement",
  17458. isMany: true
  17459. },
  17460. {
  17461. name: "diagrams",
  17462. isMany: true,
  17463. type: "bpmndi:BPMNDiagram"
  17464. },
  17465. {
  17466. name: "exporter",
  17467. isAttr: true,
  17468. type: "String"
  17469. },
  17470. {
  17471. name: "relationships",
  17472. type: "Relationship",
  17473. isMany: true
  17474. },
  17475. {
  17476. name: "exporterVersion",
  17477. isAttr: true,
  17478. type: "String"
  17479. }
  17480. ]
  17481. }
  17482. ];
  17483. var enumerations$3 = [
  17484. {
  17485. name: "ProcessType",
  17486. literalValues: [
  17487. {
  17488. name: "None"
  17489. },
  17490. {
  17491. name: "Public"
  17492. },
  17493. {
  17494. name: "Private"
  17495. }
  17496. ]
  17497. },
  17498. {
  17499. name: "GatewayDirection",
  17500. literalValues: [
  17501. {
  17502. name: "Unspecified"
  17503. },
  17504. {
  17505. name: "Converging"
  17506. },
  17507. {
  17508. name: "Diverging"
  17509. },
  17510. {
  17511. name: "Mixed"
  17512. }
  17513. ]
  17514. },
  17515. {
  17516. name: "EventBasedGatewayType",
  17517. literalValues: [
  17518. {
  17519. name: "Parallel"
  17520. },
  17521. {
  17522. name: "Exclusive"
  17523. }
  17524. ]
  17525. },
  17526. {
  17527. name: "RelationshipDirection",
  17528. literalValues: [
  17529. {
  17530. name: "None"
  17531. },
  17532. {
  17533. name: "Forward"
  17534. },
  17535. {
  17536. name: "Backward"
  17537. },
  17538. {
  17539. name: "Both"
  17540. }
  17541. ]
  17542. },
  17543. {
  17544. name: "ItemKind",
  17545. literalValues: [
  17546. {
  17547. name: "Physical"
  17548. },
  17549. {
  17550. name: "Information"
  17551. }
  17552. ]
  17553. },
  17554. {
  17555. name: "ChoreographyLoopType",
  17556. literalValues: [
  17557. {
  17558. name: "None"
  17559. },
  17560. {
  17561. name: "Standard"
  17562. },
  17563. {
  17564. name: "MultiInstanceSequential"
  17565. },
  17566. {
  17567. name: "MultiInstanceParallel"
  17568. }
  17569. ]
  17570. },
  17571. {
  17572. name: "AssociationDirection",
  17573. literalValues: [
  17574. {
  17575. name: "None"
  17576. },
  17577. {
  17578. name: "One"
  17579. },
  17580. {
  17581. name: "Both"
  17582. }
  17583. ]
  17584. },
  17585. {
  17586. name: "MultiInstanceBehavior",
  17587. literalValues: [
  17588. {
  17589. name: "None"
  17590. },
  17591. {
  17592. name: "One"
  17593. },
  17594. {
  17595. name: "All"
  17596. },
  17597. {
  17598. name: "Complex"
  17599. }
  17600. ]
  17601. },
  17602. {
  17603. name: "AdHocOrdering",
  17604. literalValues: [
  17605. {
  17606. name: "Parallel"
  17607. },
  17608. {
  17609. name: "Sequential"
  17610. }
  17611. ]
  17612. }
  17613. ];
  17614. var xml$1 = {
  17615. tagAlias: "lowerCase",
  17616. typePrefix: "t"
  17617. };
  17618. var BpmnPackage = {
  17619. name: name$5,
  17620. uri: uri$5,
  17621. prefix: prefix$5,
  17622. associations: associations$5,
  17623. types: types$5,
  17624. enumerations: enumerations$3,
  17625. xml: xml$1
  17626. };
  17627. var name$4 = "BPMNDI";
  17628. var uri$4 = "http://www.omg.org/spec/BPMN/20100524/DI";
  17629. var prefix$4 = "bpmndi";
  17630. var types$4 = [
  17631. {
  17632. name: "BPMNDiagram",
  17633. properties: [
  17634. {
  17635. name: "plane",
  17636. type: "BPMNPlane",
  17637. redefines: "di:Diagram#rootElement"
  17638. },
  17639. {
  17640. name: "labelStyle",
  17641. type: "BPMNLabelStyle",
  17642. isMany: true
  17643. }
  17644. ],
  17645. superClass: [
  17646. "di:Diagram"
  17647. ]
  17648. },
  17649. {
  17650. name: "BPMNPlane",
  17651. properties: [
  17652. {
  17653. name: "bpmnElement",
  17654. isAttr: true,
  17655. isReference: true,
  17656. type: "bpmn:BaseElement",
  17657. redefines: "di:DiagramElement#modelElement"
  17658. }
  17659. ],
  17660. superClass: [
  17661. "di:Plane"
  17662. ]
  17663. },
  17664. {
  17665. name: "BPMNShape",
  17666. properties: [
  17667. {
  17668. name: "bpmnElement",
  17669. isAttr: true,
  17670. isReference: true,
  17671. type: "bpmn:BaseElement",
  17672. redefines: "di:DiagramElement#modelElement"
  17673. },
  17674. {
  17675. name: "isHorizontal",
  17676. isAttr: true,
  17677. type: "Boolean"
  17678. },
  17679. {
  17680. name: "isExpanded",
  17681. isAttr: true,
  17682. type: "Boolean"
  17683. },
  17684. {
  17685. name: "isMarkerVisible",
  17686. isAttr: true,
  17687. type: "Boolean"
  17688. },
  17689. {
  17690. name: "label",
  17691. type: "BPMNLabel"
  17692. },
  17693. {
  17694. name: "isMessageVisible",
  17695. isAttr: true,
  17696. type: "Boolean"
  17697. },
  17698. {
  17699. name: "participantBandKind",
  17700. type: "ParticipantBandKind",
  17701. isAttr: true
  17702. },
  17703. {
  17704. name: "choreographyActivityShape",
  17705. type: "BPMNShape",
  17706. isAttr: true,
  17707. isReference: true
  17708. }
  17709. ],
  17710. superClass: [
  17711. "di:LabeledShape"
  17712. ]
  17713. },
  17714. {
  17715. name: "BPMNEdge",
  17716. properties: [
  17717. {
  17718. name: "label",
  17719. type: "BPMNLabel"
  17720. },
  17721. {
  17722. name: "bpmnElement",
  17723. isAttr: true,
  17724. isReference: true,
  17725. type: "bpmn:BaseElement",
  17726. redefines: "di:DiagramElement#modelElement"
  17727. },
  17728. {
  17729. name: "sourceElement",
  17730. isAttr: true,
  17731. isReference: true,
  17732. type: "di:DiagramElement",
  17733. redefines: "di:Edge#source"
  17734. },
  17735. {
  17736. name: "targetElement",
  17737. isAttr: true,
  17738. isReference: true,
  17739. type: "di:DiagramElement",
  17740. redefines: "di:Edge#target"
  17741. },
  17742. {
  17743. name: "messageVisibleKind",
  17744. type: "MessageVisibleKind",
  17745. isAttr: true,
  17746. "default": "initiating"
  17747. }
  17748. ],
  17749. superClass: [
  17750. "di:LabeledEdge"
  17751. ]
  17752. },
  17753. {
  17754. name: "BPMNLabel",
  17755. properties: [
  17756. {
  17757. name: "labelStyle",
  17758. type: "BPMNLabelStyle",
  17759. isAttr: true,
  17760. isReference: true,
  17761. redefines: "di:DiagramElement#style"
  17762. }
  17763. ],
  17764. superClass: [
  17765. "di:Label"
  17766. ]
  17767. },
  17768. {
  17769. name: "BPMNLabelStyle",
  17770. properties: [
  17771. {
  17772. name: "font",
  17773. type: "dc:Font"
  17774. }
  17775. ],
  17776. superClass: [
  17777. "di:Style"
  17778. ]
  17779. }
  17780. ];
  17781. var enumerations$2 = [
  17782. {
  17783. name: "ParticipantBandKind",
  17784. literalValues: [
  17785. {
  17786. name: "top_initiating"
  17787. },
  17788. {
  17789. name: "middle_initiating"
  17790. },
  17791. {
  17792. name: "bottom_initiating"
  17793. },
  17794. {
  17795. name: "top_non_initiating"
  17796. },
  17797. {
  17798. name: "middle_non_initiating"
  17799. },
  17800. {
  17801. name: "bottom_non_initiating"
  17802. }
  17803. ]
  17804. },
  17805. {
  17806. name: "MessageVisibleKind",
  17807. literalValues: [
  17808. {
  17809. name: "initiating"
  17810. },
  17811. {
  17812. name: "non_initiating"
  17813. }
  17814. ]
  17815. }
  17816. ];
  17817. var associations$4 = [
  17818. ];
  17819. var BpmnDiPackage = {
  17820. name: name$4,
  17821. uri: uri$4,
  17822. prefix: prefix$4,
  17823. types: types$4,
  17824. enumerations: enumerations$2,
  17825. associations: associations$4
  17826. };
  17827. var name$3 = "DC";
  17828. var uri$3 = "http://www.omg.org/spec/DD/20100524/DC";
  17829. var prefix$3 = "dc";
  17830. var types$3 = [
  17831. {
  17832. name: "Boolean"
  17833. },
  17834. {
  17835. name: "Integer"
  17836. },
  17837. {
  17838. name: "Real"
  17839. },
  17840. {
  17841. name: "String"
  17842. },
  17843. {
  17844. name: "Font",
  17845. properties: [
  17846. {
  17847. name: "name",
  17848. type: "String",
  17849. isAttr: true
  17850. },
  17851. {
  17852. name: "size",
  17853. type: "Real",
  17854. isAttr: true
  17855. },
  17856. {
  17857. name: "isBold",
  17858. type: "Boolean",
  17859. isAttr: true
  17860. },
  17861. {
  17862. name: "isItalic",
  17863. type: "Boolean",
  17864. isAttr: true
  17865. },
  17866. {
  17867. name: "isUnderline",
  17868. type: "Boolean",
  17869. isAttr: true
  17870. },
  17871. {
  17872. name: "isStrikeThrough",
  17873. type: "Boolean",
  17874. isAttr: true
  17875. }
  17876. ]
  17877. },
  17878. {
  17879. name: "Point",
  17880. properties: [
  17881. {
  17882. name: "x",
  17883. type: "Real",
  17884. "default": "0",
  17885. isAttr: true
  17886. },
  17887. {
  17888. name: "y",
  17889. type: "Real",
  17890. "default": "0",
  17891. isAttr: true
  17892. }
  17893. ]
  17894. },
  17895. {
  17896. name: "Bounds",
  17897. properties: [
  17898. {
  17899. name: "x",
  17900. type: "Real",
  17901. "default": "0",
  17902. isAttr: true
  17903. },
  17904. {
  17905. name: "y",
  17906. type: "Real",
  17907. "default": "0",
  17908. isAttr: true
  17909. },
  17910. {
  17911. name: "width",
  17912. type: "Real",
  17913. isAttr: true
  17914. },
  17915. {
  17916. name: "height",
  17917. type: "Real",
  17918. isAttr: true
  17919. }
  17920. ]
  17921. }
  17922. ];
  17923. var associations$3 = [
  17924. ];
  17925. var DcPackage = {
  17926. name: name$3,
  17927. uri: uri$3,
  17928. prefix: prefix$3,
  17929. types: types$3,
  17930. associations: associations$3
  17931. };
  17932. var name$2 = "DI";
  17933. var uri$2 = "http://www.omg.org/spec/DD/20100524/DI";
  17934. var prefix$2 = "di";
  17935. var types$2 = [
  17936. {
  17937. name: "DiagramElement",
  17938. isAbstract: true,
  17939. properties: [
  17940. {
  17941. name: "id",
  17942. isAttr: true,
  17943. isId: true,
  17944. type: "String"
  17945. },
  17946. {
  17947. name: "extension",
  17948. type: "Extension"
  17949. },
  17950. {
  17951. name: "owningDiagram",
  17952. type: "Diagram",
  17953. isReadOnly: true,
  17954. isVirtual: true,
  17955. isReference: true
  17956. },
  17957. {
  17958. name: "owningElement",
  17959. type: "DiagramElement",
  17960. isReadOnly: true,
  17961. isVirtual: true,
  17962. isReference: true
  17963. },
  17964. {
  17965. name: "modelElement",
  17966. isReadOnly: true,
  17967. isVirtual: true,
  17968. isReference: true,
  17969. type: "Element"
  17970. },
  17971. {
  17972. name: "style",
  17973. type: "Style",
  17974. isReadOnly: true,
  17975. isVirtual: true,
  17976. isReference: true
  17977. },
  17978. {
  17979. name: "ownedElement",
  17980. type: "DiagramElement",
  17981. isReadOnly: true,
  17982. isMany: true,
  17983. isVirtual: true
  17984. }
  17985. ]
  17986. },
  17987. {
  17988. name: "Node",
  17989. isAbstract: true,
  17990. superClass: [
  17991. "DiagramElement"
  17992. ]
  17993. },
  17994. {
  17995. name: "Edge",
  17996. isAbstract: true,
  17997. superClass: [
  17998. "DiagramElement"
  17999. ],
  18000. properties: [
  18001. {
  18002. name: "source",
  18003. type: "DiagramElement",
  18004. isReadOnly: true,
  18005. isVirtual: true,
  18006. isReference: true
  18007. },
  18008. {
  18009. name: "target",
  18010. type: "DiagramElement",
  18011. isReadOnly: true,
  18012. isVirtual: true,
  18013. isReference: true
  18014. },
  18015. {
  18016. name: "waypoint",
  18017. isUnique: false,
  18018. isMany: true,
  18019. type: "dc:Point",
  18020. xml: {
  18021. serialize: "xsi:type"
  18022. }
  18023. }
  18024. ]
  18025. },
  18026. {
  18027. name: "Diagram",
  18028. isAbstract: true,
  18029. properties: [
  18030. {
  18031. name: "id",
  18032. isAttr: true,
  18033. isId: true,
  18034. type: "String"
  18035. },
  18036. {
  18037. name: "rootElement",
  18038. type: "DiagramElement",
  18039. isReadOnly: true,
  18040. isVirtual: true
  18041. },
  18042. {
  18043. name: "name",
  18044. isAttr: true,
  18045. type: "String"
  18046. },
  18047. {
  18048. name: "documentation",
  18049. isAttr: true,
  18050. type: "String"
  18051. },
  18052. {
  18053. name: "resolution",
  18054. isAttr: true,
  18055. type: "Real"
  18056. },
  18057. {
  18058. name: "ownedStyle",
  18059. type: "Style",
  18060. isReadOnly: true,
  18061. isMany: true,
  18062. isVirtual: true
  18063. }
  18064. ]
  18065. },
  18066. {
  18067. name: "Shape",
  18068. isAbstract: true,
  18069. superClass: [
  18070. "Node"
  18071. ],
  18072. properties: [
  18073. {
  18074. name: "bounds",
  18075. type: "dc:Bounds"
  18076. }
  18077. ]
  18078. },
  18079. {
  18080. name: "Plane",
  18081. isAbstract: true,
  18082. superClass: [
  18083. "Node"
  18084. ],
  18085. properties: [
  18086. {
  18087. name: "planeElement",
  18088. type: "DiagramElement",
  18089. subsettedProperty: "DiagramElement-ownedElement",
  18090. isMany: true
  18091. }
  18092. ]
  18093. },
  18094. {
  18095. name: "LabeledEdge",
  18096. isAbstract: true,
  18097. superClass: [
  18098. "Edge"
  18099. ],
  18100. properties: [
  18101. {
  18102. name: "ownedLabel",
  18103. type: "Label",
  18104. isReadOnly: true,
  18105. subsettedProperty: "DiagramElement-ownedElement",
  18106. isMany: true,
  18107. isVirtual: true
  18108. }
  18109. ]
  18110. },
  18111. {
  18112. name: "LabeledShape",
  18113. isAbstract: true,
  18114. superClass: [
  18115. "Shape"
  18116. ],
  18117. properties: [
  18118. {
  18119. name: "ownedLabel",
  18120. type: "Label",
  18121. isReadOnly: true,
  18122. subsettedProperty: "DiagramElement-ownedElement",
  18123. isMany: true,
  18124. isVirtual: true
  18125. }
  18126. ]
  18127. },
  18128. {
  18129. name: "Label",
  18130. isAbstract: true,
  18131. superClass: [
  18132. "Node"
  18133. ],
  18134. properties: [
  18135. {
  18136. name: "bounds",
  18137. type: "dc:Bounds"
  18138. }
  18139. ]
  18140. },
  18141. {
  18142. name: "Style",
  18143. isAbstract: true,
  18144. properties: [
  18145. {
  18146. name: "id",
  18147. isAttr: true,
  18148. isId: true,
  18149. type: "String"
  18150. }
  18151. ]
  18152. },
  18153. {
  18154. name: "Extension",
  18155. properties: [
  18156. {
  18157. name: "values",
  18158. isMany: true,
  18159. type: "Element"
  18160. }
  18161. ]
  18162. }
  18163. ];
  18164. var associations$2 = [
  18165. ];
  18166. var xml = {
  18167. tagAlias: "lowerCase"
  18168. };
  18169. var DiPackage = {
  18170. name: name$2,
  18171. uri: uri$2,
  18172. prefix: prefix$2,
  18173. types: types$2,
  18174. associations: associations$2,
  18175. xml: xml
  18176. };
  18177. var name$1 = "bpmn.io colors for BPMN";
  18178. var uri$1 = "http://bpmn.io/schema/bpmn/biocolor/1.0";
  18179. var prefix$1 = "bioc";
  18180. var types$1 = [
  18181. {
  18182. name: "ColoredShape",
  18183. "extends": [
  18184. "bpmndi:BPMNShape"
  18185. ],
  18186. properties: [
  18187. {
  18188. name: "stroke",
  18189. isAttr: true,
  18190. type: "String"
  18191. },
  18192. {
  18193. name: "fill",
  18194. isAttr: true,
  18195. type: "String"
  18196. }
  18197. ]
  18198. },
  18199. {
  18200. name: "ColoredEdge",
  18201. "extends": [
  18202. "bpmndi:BPMNEdge"
  18203. ],
  18204. properties: [
  18205. {
  18206. name: "stroke",
  18207. isAttr: true,
  18208. type: "String"
  18209. },
  18210. {
  18211. name: "fill",
  18212. isAttr: true,
  18213. type: "String"
  18214. }
  18215. ]
  18216. }
  18217. ];
  18218. var enumerations$1 = [
  18219. ];
  18220. var associations$1 = [
  18221. ];
  18222. var BiocPackage = {
  18223. name: name$1,
  18224. uri: uri$1,
  18225. prefix: prefix$1,
  18226. types: types$1,
  18227. enumerations: enumerations$1,
  18228. associations: associations$1
  18229. };
  18230. var name = "BPMN in Color";
  18231. var uri = "http://www.omg.org/spec/BPMN/non-normative/color/1.0";
  18232. var prefix = "color";
  18233. var types = [
  18234. {
  18235. name: "ColoredLabel",
  18236. "extends": [
  18237. "bpmndi:BPMNLabel"
  18238. ],
  18239. properties: [
  18240. {
  18241. name: "color",
  18242. isAttr: true,
  18243. type: "String"
  18244. }
  18245. ]
  18246. },
  18247. {
  18248. name: "ColoredShape",
  18249. "extends": [
  18250. "bpmndi:BPMNShape"
  18251. ],
  18252. properties: [
  18253. {
  18254. name: "background-color",
  18255. isAttr: true,
  18256. type: "String"
  18257. },
  18258. {
  18259. name: "border-color",
  18260. isAttr: true,
  18261. type: "String"
  18262. }
  18263. ]
  18264. },
  18265. {
  18266. name: "ColoredEdge",
  18267. "extends": [
  18268. "bpmndi:BPMNEdge"
  18269. ],
  18270. properties: [
  18271. {
  18272. name: "border-color",
  18273. isAttr: true,
  18274. type: "String"
  18275. }
  18276. ]
  18277. }
  18278. ];
  18279. var enumerations = [
  18280. ];
  18281. var associations = [
  18282. ];
  18283. var BpmnInColorPackage = {
  18284. name: name,
  18285. uri: uri,
  18286. prefix: prefix,
  18287. types: types,
  18288. enumerations: enumerations,
  18289. associations: associations
  18290. };
  18291. var packages = {
  18292. bpmn: BpmnPackage,
  18293. bpmndi: BpmnDiPackage,
  18294. dc: DcPackage,
  18295. di: DiPackage,
  18296. bioc: BiocPackage,
  18297. color: BpmnInColorPackage
  18298. };
  18299. function simple(additionalPackages, options) {
  18300. var pks = assign$1({}, packages, additionalPackages);
  18301. return new BpmnModdle(pks, options);
  18302. }
  18303. /**
  18304. * @typedef {import('../model/Types').ModdleElement} ModdleElement
  18305. */
  18306. // TODO(nikku): remove with future bpmn-js version
  18307. var DI_ERROR_MESSAGE = 'Tried to access di from the businessObject. The di is available through the diagram element only. For more information, see https://github.com/bpmn-io/bpmn-js/issues/1472';
  18308. /**
  18309. * @private
  18310. *
  18311. * @param {ModdleElement} businessObject
  18312. */
  18313. function ensureCompatDiRef(businessObject) {
  18314. // bpmnElement can have multiple independent DIs
  18315. if (!has$1(businessObject, 'di')) {
  18316. Object.defineProperty(businessObject, 'di', {
  18317. enumerable: false,
  18318. get: function() {
  18319. throw new Error(DI_ERROR_MESSAGE);
  18320. }
  18321. });
  18322. }
  18323. }
  18324. /**
  18325. * @typedef {import('diagram-js/lib/i18n/translate/translate').default} Translate
  18326. *
  18327. * @typedef {import('../model/Types').ModdleElement} ModdleElement
  18328. */
  18329. /**
  18330. * Returns true if an element is of the given meta-model type.
  18331. *
  18332. * @param {ModdleElement} element
  18333. * @param {string} type
  18334. *
  18335. * @return {boolean}
  18336. */
  18337. function is(element, type) {
  18338. return element.$instanceOf(type);
  18339. }
  18340. /**
  18341. * Find a suitable display candidate for definitions where the DI does not
  18342. * correctly specify one.
  18343. *
  18344. * @param {ModdleElement} definitions
  18345. *
  18346. * @return {ModdleElement}
  18347. */
  18348. function findDisplayCandidate(definitions) {
  18349. return find(definitions.rootElements, function(e) {
  18350. return is(e, 'bpmn:Process') || is(e, 'bpmn:Collaboration');
  18351. });
  18352. }
  18353. /**
  18354. * @param {Record<'element' | 'root' | 'error', Function>} handler
  18355. * @param {Translate} translate
  18356. */
  18357. function BpmnTreeWalker(handler, translate) {
  18358. // list of containers already walked
  18359. var handledElements = {};
  18360. // list of elements to handle deferred to ensure
  18361. // prerequisites are drawn
  18362. var deferred = [];
  18363. var diMap = {};
  18364. // Helpers //////////////////////
  18365. function contextual(fn, ctx) {
  18366. return function(e) {
  18367. fn(e, ctx);
  18368. };
  18369. }
  18370. function handled(element) {
  18371. handledElements[element.id] = element;
  18372. }
  18373. function isHandled(element) {
  18374. return handledElements[element.id];
  18375. }
  18376. function visit(element, ctx) {
  18377. var gfx = element.gfx;
  18378. // avoid multiple rendering of elements
  18379. if (gfx) {
  18380. throw new Error(
  18381. translate('already rendered {element}', { element: elementToString(element) })
  18382. );
  18383. }
  18384. // call handler
  18385. return handler.element(element, diMap[element.id], ctx);
  18386. }
  18387. function visitRoot(element, diagram) {
  18388. return handler.root(element, diMap[element.id], diagram);
  18389. }
  18390. function visitIfDi(element, ctx) {
  18391. try {
  18392. var gfx = diMap[element.id] && visit(element, ctx);
  18393. handled(element);
  18394. return gfx;
  18395. } catch (e) {
  18396. logError(e.message, { element: element, error: e });
  18397. console.error(translate('failed to import {element}', { element: elementToString(element) }));
  18398. console.error(e);
  18399. }
  18400. }
  18401. function logError(message, context) {
  18402. handler.error(message, context);
  18403. }
  18404. // DI handling //////////////////////
  18405. var registerDi = this.registerDi = function registerDi(di) {
  18406. var bpmnElement = di.bpmnElement;
  18407. if (bpmnElement) {
  18408. if (diMap[bpmnElement.id]) {
  18409. logError(
  18410. translate('multiple DI elements defined for {element}', {
  18411. element: elementToString(bpmnElement)
  18412. }),
  18413. { element: bpmnElement }
  18414. );
  18415. } else {
  18416. diMap[bpmnElement.id] = di;
  18417. ensureCompatDiRef(bpmnElement);
  18418. }
  18419. } else {
  18420. logError(
  18421. translate('no bpmnElement referenced in {element}', {
  18422. element: elementToString(di)
  18423. }),
  18424. { element: di }
  18425. );
  18426. }
  18427. };
  18428. function handleDiagram(diagram) {
  18429. handlePlane(diagram.plane);
  18430. }
  18431. function handlePlane(plane) {
  18432. registerDi(plane);
  18433. forEach$1(plane.planeElement, handlePlaneElement);
  18434. }
  18435. function handlePlaneElement(planeElement) {
  18436. registerDi(planeElement);
  18437. }
  18438. // Semantic handling //////////////////////
  18439. /**
  18440. * Handle definitions and return the rendered diagram (if any).
  18441. *
  18442. * @param {ModdleElement} definitions to walk and import
  18443. * @param {ModdleElement} [diagram] specific diagram to import and display
  18444. *
  18445. * @throws {Error} if no diagram to display could be found
  18446. */
  18447. this.handleDefinitions = function handleDefinitions(definitions, diagram) {
  18448. // make sure we walk the correct bpmnElement
  18449. var diagrams = definitions.diagrams;
  18450. if (diagram && diagrams.indexOf(diagram) === -1) {
  18451. throw new Error(translate('diagram not part of bpmn:Definitions'));
  18452. }
  18453. if (!diagram && diagrams && diagrams.length) {
  18454. diagram = diagrams[0];
  18455. }
  18456. // no diagram -> nothing to import
  18457. if (!diagram) {
  18458. throw new Error(translate('no diagram to display'));
  18459. }
  18460. // load DI from selected diagram only
  18461. diMap = {};
  18462. handleDiagram(diagram);
  18463. var plane = diagram.plane;
  18464. if (!plane) {
  18465. throw new Error(translate(
  18466. 'no plane for {element}',
  18467. { element: elementToString(diagram) }
  18468. ));
  18469. }
  18470. var rootElement = plane.bpmnElement;
  18471. // ensure we default to a suitable display candidate (process or collaboration),
  18472. // even if non is specified in DI
  18473. if (!rootElement) {
  18474. rootElement = findDisplayCandidate(definitions);
  18475. if (!rootElement) {
  18476. throw new Error(translate('no process or collaboration to display'));
  18477. } else {
  18478. logError(
  18479. translate('correcting missing bpmnElement on {plane} to {rootElement}', {
  18480. plane: elementToString(plane),
  18481. rootElement: elementToString(rootElement)
  18482. })
  18483. );
  18484. // correct DI on the fly
  18485. plane.bpmnElement = rootElement;
  18486. registerDi(plane);
  18487. }
  18488. }
  18489. var ctx = visitRoot(rootElement, plane);
  18490. if (is(rootElement, 'bpmn:Process') || is(rootElement, 'bpmn:SubProcess')) {
  18491. handleProcess(rootElement, ctx);
  18492. } else if (is(rootElement, 'bpmn:Collaboration')) {
  18493. handleCollaboration(rootElement, ctx);
  18494. // force drawing of everything not yet drawn that is part of the target DI
  18495. handleUnhandledProcesses(definitions.rootElements, ctx);
  18496. } else {
  18497. throw new Error(
  18498. translate('unsupported bpmnElement for {plane}: {rootElement}', {
  18499. plane: elementToString(plane),
  18500. rootElement: elementToString(rootElement)
  18501. })
  18502. );
  18503. }
  18504. // handle all deferred elements
  18505. handleDeferred(deferred);
  18506. };
  18507. var handleDeferred = this.handleDeferred = function handleDeferred() {
  18508. var fn;
  18509. // drain deferred until empty
  18510. while (deferred.length) {
  18511. fn = deferred.shift();
  18512. fn();
  18513. }
  18514. };
  18515. function handleProcess(process, context) {
  18516. handleFlowElementsContainer(process, context);
  18517. handleIoSpecification(process.ioSpecification, context);
  18518. handleArtifacts(process.artifacts, context);
  18519. // log process handled
  18520. handled(process);
  18521. }
  18522. function handleUnhandledProcesses(rootElements, ctx) {
  18523. // walk through all processes that have not yet been drawn and draw them
  18524. // if they contain lanes with DI information.
  18525. // we do this to pass the free-floating lane test cases in the MIWG test suite
  18526. var processes = filter(rootElements, function(e) {
  18527. return !isHandled(e) && is(e, 'bpmn:Process') && e.laneSets;
  18528. });
  18529. processes.forEach(contextual(handleProcess, ctx));
  18530. }
  18531. function handleMessageFlow(messageFlow, context) {
  18532. visitIfDi(messageFlow, context);
  18533. }
  18534. function handleMessageFlows(messageFlows, context) {
  18535. forEach$1(messageFlows, contextual(handleMessageFlow, context));
  18536. }
  18537. function handleDataAssociation(association, context) {
  18538. visitIfDi(association, context);
  18539. }
  18540. function handleDataInput(dataInput, context) {
  18541. visitIfDi(dataInput, context);
  18542. }
  18543. function handleDataOutput(dataOutput, context) {
  18544. visitIfDi(dataOutput, context);
  18545. }
  18546. function handleArtifact(artifact, context) {
  18547. // bpmn:TextAnnotation
  18548. // bpmn:Group
  18549. // bpmn:Association
  18550. visitIfDi(artifact, context);
  18551. }
  18552. function handleArtifacts(artifacts, context) {
  18553. forEach$1(artifacts, function(e) {
  18554. if (is(e, 'bpmn:Association')) {
  18555. deferred.push(function() {
  18556. handleArtifact(e, context);
  18557. });
  18558. } else {
  18559. handleArtifact(e, context);
  18560. }
  18561. });
  18562. }
  18563. function handleIoSpecification(ioSpecification, context) {
  18564. if (!ioSpecification) {
  18565. return;
  18566. }
  18567. forEach$1(ioSpecification.dataInputs, contextual(handleDataInput, context));
  18568. forEach$1(ioSpecification.dataOutputs, contextual(handleDataOutput, context));
  18569. }
  18570. var handleSubProcess = this.handleSubProcess = function handleSubProcess(subProcess, context) {
  18571. handleFlowElementsContainer(subProcess, context);
  18572. handleArtifacts(subProcess.artifacts, context);
  18573. };
  18574. function handleFlowNode(flowNode, context) {
  18575. var childCtx = visitIfDi(flowNode, context);
  18576. if (is(flowNode, 'bpmn:SubProcess')) {
  18577. handleSubProcess(flowNode, childCtx || context);
  18578. }
  18579. if (is(flowNode, 'bpmn:Activity')) {
  18580. handleIoSpecification(flowNode.ioSpecification, context);
  18581. }
  18582. // defer handling of associations
  18583. // affected types:
  18584. //
  18585. // * bpmn:Activity
  18586. // * bpmn:ThrowEvent
  18587. // * bpmn:CatchEvent
  18588. //
  18589. deferred.push(function() {
  18590. forEach$1(flowNode.dataInputAssociations, contextual(handleDataAssociation, context));
  18591. forEach$1(flowNode.dataOutputAssociations, contextual(handleDataAssociation, context));
  18592. });
  18593. }
  18594. function handleSequenceFlow(sequenceFlow, context) {
  18595. visitIfDi(sequenceFlow, context);
  18596. }
  18597. function handleDataElement(dataObject, context) {
  18598. visitIfDi(dataObject, context);
  18599. }
  18600. function handleLane(lane, context) {
  18601. deferred.push(function() {
  18602. var newContext = visitIfDi(lane, context);
  18603. if (lane.childLaneSet) {
  18604. handleLaneSet(lane.childLaneSet, newContext || context);
  18605. }
  18606. wireFlowNodeRefs(lane);
  18607. });
  18608. }
  18609. function handleLaneSet(laneSet, context) {
  18610. forEach$1(laneSet.lanes, contextual(handleLane, context));
  18611. }
  18612. function handleLaneSets(laneSets, context) {
  18613. forEach$1(laneSets, contextual(handleLaneSet, context));
  18614. }
  18615. function handleFlowElementsContainer(container, context) {
  18616. handleFlowElements(container.flowElements, context);
  18617. if (container.laneSets) {
  18618. handleLaneSets(container.laneSets, context);
  18619. }
  18620. }
  18621. function handleFlowElements(flowElements, context) {
  18622. forEach$1(flowElements, function(e) {
  18623. if (is(e, 'bpmn:SequenceFlow')) {
  18624. deferred.push(function() {
  18625. handleSequenceFlow(e, context);
  18626. });
  18627. } else if (is(e, 'bpmn:BoundaryEvent')) {
  18628. deferred.unshift(function() {
  18629. handleFlowNode(e, context);
  18630. });
  18631. } else if (is(e, 'bpmn:FlowNode')) {
  18632. handleFlowNode(e, context);
  18633. } else if (is(e, 'bpmn:DataObject')) ; else if (is(e, 'bpmn:DataStoreReference')) {
  18634. handleDataElement(e, context);
  18635. } else if (is(e, 'bpmn:DataObjectReference')) {
  18636. handleDataElement(e, context);
  18637. } else {
  18638. logError(
  18639. translate('unrecognized flowElement {element} in context {context}', {
  18640. element: elementToString(e),
  18641. context: (context ? elementToString(context.businessObject) : 'null')
  18642. }),
  18643. { element: e, context: context }
  18644. );
  18645. }
  18646. });
  18647. }
  18648. function handleParticipant(participant, context) {
  18649. var newCtx = visitIfDi(participant, context);
  18650. var process = participant.processRef;
  18651. if (process) {
  18652. handleProcess(process, newCtx || context);
  18653. }
  18654. }
  18655. function handleCollaboration(collaboration, context) {
  18656. forEach$1(collaboration.participants, contextual(handleParticipant, context));
  18657. handleArtifacts(collaboration.artifacts, context);
  18658. // handle message flows latest in the process
  18659. deferred.push(function() {
  18660. handleMessageFlows(collaboration.messageFlows, context);
  18661. });
  18662. }
  18663. function wireFlowNodeRefs(lane) {
  18664. // wire the virtual flowNodeRefs <-> relationship
  18665. forEach$1(lane.flowNodeRef, function(flowNode) {
  18666. var lanes = flowNode.get('lanes');
  18667. if (lanes) {
  18668. lanes.push(lane);
  18669. }
  18670. });
  18671. }
  18672. }
  18673. /**
  18674. * @typedef {import('../model/Types').ModdleElement} ModdleElement
  18675. *
  18676. * @typedef { {
  18677. * warnings: string[];
  18678. * } } ImportBPMNDiagramResult
  18679. *
  18680. * @typedef {ImportBPMNDiagramResult & Error} ImportBPMNDiagramError
  18681. */
  18682. /**
  18683. * Import the definitions into a diagram.
  18684. *
  18685. * Errors and warnings are reported through the specified callback.
  18686. *
  18687. * @param {ModdleElement} diagram
  18688. * @param {ModdleElement} definitions
  18689. * @param {ModdleElement} [bpmnDiagram] The diagram to be rendered (if not
  18690. * provided, the first one will be rendered).
  18691. *
  18692. * @return {Promise<ImportBPMNDiagramResult>}
  18693. */
  18694. function importBpmnDiagram(diagram, definitions, bpmnDiagram) {
  18695. var importer,
  18696. eventBus,
  18697. translate,
  18698. canvas;
  18699. var error,
  18700. warnings = [];
  18701. /**
  18702. * Walk the diagram semantically, importing (=drawing)
  18703. * all elements you encounter.
  18704. *
  18705. * @param {ModdleElement} definitions
  18706. * @param {ModdleElement} bpmnDiagram
  18707. */
  18708. function render(definitions, bpmnDiagram) {
  18709. var visitor = {
  18710. root: function(element, di) {
  18711. return importer.add(element, di);
  18712. },
  18713. element: function(element, di, parentShape) {
  18714. return importer.add(element, di, parentShape);
  18715. },
  18716. error: function(message, context) {
  18717. warnings.push({ message: message, context: context });
  18718. }
  18719. };
  18720. var walker = new BpmnTreeWalker(visitor, translate);
  18721. bpmnDiagram = bpmnDiagram || (definitions.diagrams && definitions.diagrams[0]);
  18722. var diagramsToImport = getDiagramsToImport(definitions, bpmnDiagram);
  18723. if (!diagramsToImport) {
  18724. throw new Error(translate('no diagram to display'));
  18725. }
  18726. // traverse BPMN 2.0 document model,
  18727. // starting at definitions
  18728. forEach$1(diagramsToImport, function(diagram) {
  18729. walker.handleDefinitions(definitions, diagram);
  18730. });
  18731. var rootId = bpmnDiagram.plane.bpmnElement.id;
  18732. // we do need to account for different ways we create root elements
  18733. // each nested imported <root> do have the `_plane` suffix, while
  18734. // the root <root> is found under the business object ID
  18735. canvas.setRootElement(
  18736. canvas.findRoot(rootId + '_plane') || canvas.findRoot(rootId)
  18737. );
  18738. }
  18739. return new Promise(function(resolve, reject) {
  18740. try {
  18741. importer = diagram.get('bpmnImporter');
  18742. eventBus = diagram.get('eventBus');
  18743. translate = diagram.get('translate');
  18744. canvas = diagram.get('canvas');
  18745. eventBus.fire('import.render.start', { definitions: definitions });
  18746. render(definitions, bpmnDiagram);
  18747. eventBus.fire('import.render.complete', {
  18748. error: error,
  18749. warnings: warnings
  18750. });
  18751. return resolve({ warnings: warnings });
  18752. } catch (e) {
  18753. e.warnings = warnings;
  18754. return reject(e);
  18755. }
  18756. });
  18757. }
  18758. /**
  18759. * Returns all diagrams in the same hierarchy as the requested diagram.
  18760. * Includes all parent and sub process diagrams.
  18761. *
  18762. * @param {ModdleElement} definitions
  18763. * @param {ModdleElement} bpmnDiagram
  18764. *
  18765. * @return {ModdleElement[]}
  18766. */
  18767. function getDiagramsToImport(definitions, bpmnDiagram) {
  18768. if (!bpmnDiagram) {
  18769. return;
  18770. }
  18771. var bpmnElement = bpmnDiagram.plane.bpmnElement,
  18772. rootElement = bpmnElement;
  18773. if (!is$1(bpmnElement, 'bpmn:Process') && !is$1(bpmnElement, 'bpmn:Collaboration')) {
  18774. rootElement = findRootProcess(bpmnElement);
  18775. }
  18776. // in case the process is part of a collaboration, the plane references the
  18777. // collaboration, not the process
  18778. var collaboration;
  18779. if (is$1(rootElement, 'bpmn:Collaboration')) {
  18780. collaboration = rootElement;
  18781. } else {
  18782. collaboration = find(definitions.rootElements, function(element) {
  18783. if (!is$1(element, 'bpmn:Collaboration')) {
  18784. return;
  18785. }
  18786. return find(element.participants, function(participant) {
  18787. return participant.processRef === rootElement;
  18788. });
  18789. });
  18790. }
  18791. var rootElements = [ rootElement ];
  18792. // all collaboration processes can contain sub-diagrams
  18793. if (collaboration) {
  18794. rootElements = map$1(collaboration.participants, function(participant) {
  18795. return participant.processRef;
  18796. });
  18797. rootElements.push(collaboration);
  18798. }
  18799. var allChildren = selfAndAllFlowElements(rootElements);
  18800. // if we have multiple diagrams referencing the same element, we
  18801. // use the first in the file
  18802. var diagramsToImport = [ bpmnDiagram ];
  18803. var handledElements = [ bpmnElement ];
  18804. forEach$1(definitions.diagrams, function(diagram) {
  18805. var businessObject = diagram.plane.bpmnElement;
  18806. if (
  18807. allChildren.indexOf(businessObject) !== -1 &&
  18808. handledElements.indexOf(businessObject) === -1
  18809. ) {
  18810. diagramsToImport.push(diagram);
  18811. handledElements.push(businessObject);
  18812. }
  18813. });
  18814. return diagramsToImport;
  18815. }
  18816. function selfAndAllFlowElements(elements) {
  18817. var result = [];
  18818. forEach$1(elements, function(element) {
  18819. if (!element) {
  18820. return;
  18821. }
  18822. result.push(element);
  18823. result = result.concat(selfAndAllFlowElements(element.flowElements));
  18824. });
  18825. return result;
  18826. }
  18827. function findRootProcess(element) {
  18828. var parent = element;
  18829. while (parent) {
  18830. if (is$1(parent, 'bpmn:Process')) {
  18831. return parent;
  18832. }
  18833. parent = parent.$parent;
  18834. }
  18835. }
  18836. /**
  18837. * This file must not be changed or exchanged.
  18838. *
  18839. * @see http://bpmn.io/license for more information.
  18840. */
  18841. // inlined ../../resources/logo.svg
  18842. var BPMNIO_LOGO_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.02 5.57" width="53" height="21"><path fill="currentColor" d="M1.88.92v.14c0 .41-.13.68-.4.8.33.14.46.44.46.86v.33c0 .61-.33.95-.95.95H0V0h.95c.65 0 .93.3.93.92zM.63.57v1.06h.24c.24 0 .38-.1.38-.43V.98c0-.28-.1-.4-.32-.4zm0 1.63v1.22h.36c.2 0 .32-.1.32-.39v-.35c0-.37-.12-.48-.4-.48H.63zM4.18.99v.52c0 .64-.31.98-.94.98h-.3V4h-.62V0h.92c.63 0 .94.35.94.99zM2.94.57v1.35h.3c.2 0 .3-.09.3-.37v-.6c0-.29-.1-.38-.3-.38h-.3zm2.89 2.27L6.25 0h.88v4h-.6V1.12L6.1 3.99h-.6l-.46-2.82v2.82h-.55V0h.87zM8.14 1.1V4h-.56V0h.79L9 2.4V0h.56v4h-.64zm2.49 2.29v.6h-.6v-.6zM12.12 1c0-.63.33-1 .95-1 .61 0 .95.37.95 1v2.04c0 .64-.34 1-.95 1-.62 0-.95-.37-.95-1zm.62 2.08c0 .28.13.39.33.39s.32-.1.32-.4V.98c0-.29-.12-.4-.32-.4s-.33.11-.33.4z"/><path fill="currentColor" d="M0 4.53h14.02v1.04H0zM11.08 0h.63v.62h-.63zm.63 4V1h-.63v2.98z"/></svg>';
  18843. var BPMNIO_IMG = BPMNIO_LOGO_SVG;
  18844. var LOGO_STYLES = {
  18845. verticalAlign: 'middle'
  18846. };
  18847. var LINK_STYLES = {
  18848. 'color': '#404040'
  18849. };
  18850. var LIGHTBOX_STYLES = {
  18851. 'zIndex': '1001',
  18852. 'position': 'fixed',
  18853. 'top': '0',
  18854. 'left': '0',
  18855. 'right': '0',
  18856. 'bottom': '0'
  18857. };
  18858. var BACKDROP_STYLES = {
  18859. 'width': '100%',
  18860. 'height': '100%',
  18861. 'background': 'rgba(40,40,40,0.2)'
  18862. };
  18863. var NOTICE_STYLES = {
  18864. 'position': 'absolute',
  18865. 'left': '50%',
  18866. 'top': '40%',
  18867. 'transform': 'translate(-50%)',
  18868. 'width': '260px',
  18869. 'padding': '10px',
  18870. 'background': 'white',
  18871. 'boxShadow': '0 1px 4px rgba(0,0,0,0.3)',
  18872. 'fontFamily': 'Helvetica, Arial, sans-serif',
  18873. 'fontSize': '14px',
  18874. 'display': 'flex',
  18875. 'lineHeight': '1.3'
  18876. };
  18877. var LIGHTBOX_MARKUP =
  18878. '<div class="bjs-powered-by-lightbox">' +
  18879. '<div class="backdrop"></div>' +
  18880. '<div class="notice">' +
  18881. '<a href="https://bpmn.io" target="_blank" rel="noopener" class="link">' +
  18882. BPMNIO_IMG +
  18883. '</a>' +
  18884. '<span>' +
  18885. 'Web-based tooling for BPMN, DMN and forms ' +
  18886. 'powered by <a href="https://bpmn.io" target="_blank" rel="noopener">bpmn.io</a>.' +
  18887. '</span>' +
  18888. '</div>' +
  18889. '</div>';
  18890. var lightbox;
  18891. function createLightbox() {
  18892. lightbox = domify$1(LIGHTBOX_MARKUP);
  18893. assign(lightbox, LIGHTBOX_STYLES);
  18894. assign(query('svg', lightbox), LOGO_STYLES);
  18895. assign(query('.backdrop', lightbox), BACKDROP_STYLES);
  18896. assign(query('.notice', lightbox), NOTICE_STYLES);
  18897. assign(query('.link', lightbox), LINK_STYLES, {
  18898. 'margin': '15px 20px 15px 10px',
  18899. 'alignSelf': 'center'
  18900. });
  18901. }
  18902. function open() {
  18903. if (!lightbox) {
  18904. createLightbox();
  18905. delegate.bind(lightbox, '.backdrop', 'click', function(event) {
  18906. document.body.removeChild(lightbox);
  18907. });
  18908. }
  18909. document.body.appendChild(lightbox);
  18910. }
  18911. /**
  18912. * The code in the <project-logo></project-logo> area
  18913. * must not be changed.
  18914. *
  18915. * @see http://bpmn.io/license for more information.
  18916. */
  18917. /**
  18918. * @template T
  18919. *
  18920. * @typedef {import('diagram-js/lib/core/EventBus').EventBusEventCallback<T>} EventBusEventCallback
  18921. */
  18922. /**
  18923. * @typedef {import('didi').ModuleDeclaration} ModuleDeclaration
  18924. *
  18925. * @typedef {import('./model/Types').Moddle} Moddle
  18926. * @typedef {import('./model/Types').ModdleElement} ModdleElement
  18927. * @typedef {import('./model/Types').ModdleExtension} ModdleExtension
  18928. *
  18929. * @typedef { {
  18930. * width?: number|string;
  18931. * height?: number|string;
  18932. * position?: string;
  18933. * container?: string|HTMLElement;
  18934. * moddleExtensions?: ModdleExtensions;
  18935. * additionalModules?: ModuleDeclaration[];
  18936. * } & Record<string, any> } BaseViewerOptions
  18937. *
  18938. * @typedef {Record<string, ModdleElement>} ModdleElementsById
  18939. *
  18940. * @typedef { {
  18941. * [key: string]: ModdleExtension;
  18942. * } } ModdleExtensions
  18943. *
  18944. * @typedef { {
  18945. * warnings: string[];
  18946. * } } ImportXMLResult
  18947. *
  18948. * @typedef {ImportXMLResult & Error} ImportXMLError
  18949. *
  18950. * @typedef {ImportXMLResult} ImportDefinitionsResult
  18951. *
  18952. * @typedef {ImportXMLError} ImportDefinitionsError
  18953. *
  18954. * @typedef {ImportXMLResult} OpenResult
  18955. *
  18956. * @typedef {ImportXMLError} OpenError
  18957. *
  18958. * @typedef { {
  18959. * format?: boolean;
  18960. * preamble?: boolean;
  18961. * } } SaveXMLOptions
  18962. *
  18963. * @typedef { {
  18964. * xml?: string;
  18965. * error?: Error;
  18966. * } } SaveXMLResult
  18967. *
  18968. * @typedef { {
  18969. * svg: string;
  18970. * } } SaveSVGResult
  18971. *
  18972. * @typedef { {
  18973. * xml: string;
  18974. * } } ImportParseStartEvent
  18975. *
  18976. * @typedef { {
  18977. * error?: ImportXMLError;
  18978. * definitions?: ModdleElement;
  18979. * elementsById?: ModdleElementsById;
  18980. * references?: ModdleElement[];
  18981. * warnings: string[];
  18982. * } } ImportParseCompleteEvent
  18983. *
  18984. * @typedef { {
  18985. * error?: ImportXMLError;
  18986. * warnings: string[];
  18987. * } } ImportDoneEvent
  18988. *
  18989. * @typedef { {
  18990. * definitions: ModdleElement;
  18991. * } } SaveXMLStartEvent
  18992. *
  18993. * @typedef {SaveXMLResult} SaveXMLDoneEvent
  18994. *
  18995. * @typedef { {
  18996. * error?: Error;
  18997. * svg: string;
  18998. * } } SaveSVGDoneEvent
  18999. */
  19000. /**
  19001. * A base viewer for BPMN 2.0 diagrams.
  19002. *
  19003. * Have a look at {@link Viewer}, {@link NavigatedViewer} or {@link Modeler} for
  19004. * bundles that include actual features.
  19005. *
  19006. * @param {BaseViewerOptions} [options] The options to configure the viewer.
  19007. */
  19008. function BaseViewer(options) {
  19009. /**
  19010. * @type {BaseViewerOptions}
  19011. */
  19012. options = assign$1({}, DEFAULT_OPTIONS, options);
  19013. /**
  19014. * @type {Moddle}
  19015. */
  19016. this._moddle = this._createModdle(options);
  19017. /**
  19018. * @type {HTMLElement}
  19019. */
  19020. this._container = this._createContainer(options);
  19021. /* <project-logo> */
  19022. addProjectLogo(this._container);
  19023. /* </project-logo> */
  19024. this._init(this._container, this._moddle, options);
  19025. }
  19026. e(BaseViewer, Diagram);
  19027. /**
  19028. * Parse and render a BPMN 2.0 diagram.
  19029. *
  19030. * Once finished the viewer reports back the result to the
  19031. * provided callback function with (err, warnings).
  19032. *
  19033. * ## Life-Cycle Events
  19034. *
  19035. * During import the viewer will fire life-cycle events:
  19036. *
  19037. * * import.parse.start (about to read model from XML)
  19038. * * import.parse.complete (model read; may have worked or not)
  19039. * * import.render.start (graphical import start)
  19040. * * import.render.complete (graphical import finished)
  19041. * * import.done (everything done)
  19042. *
  19043. * You can use these events to hook into the life-cycle.
  19044. *
  19045. * @throws {ImportXMLError} An error thrown during the import of the XML.
  19046. *
  19047. * @fires BaseViewer#ImportParseStartEvent
  19048. * @fires BaseViewer#ImportParseCompleteEvent
  19049. * @fires Importer#ImportRenderStartEvent
  19050. * @fires Importer#ImportRenderCompleteEvent
  19051. * @fires BaseViewer#ImportDoneEvent
  19052. *
  19053. * @param {string} xml The BPMN 2.0 XML to be imported.
  19054. * @param {ModdleElement|string} [bpmnDiagram] The optional diagram or Id of the BPMN diagram to open.
  19055. *
  19056. * @return {Promise<ImportXMLResult>} A promise resolving with warnings that were produced during the import.
  19057. */
  19058. BaseViewer.prototype.importXML = async function importXML(xml, bpmnDiagram) {
  19059. const self = this;
  19060. function ParseCompleteEvent(data) {
  19061. return self.get('eventBus').createEvent(data);
  19062. }
  19063. let aggregatedWarnings = [];
  19064. try {
  19065. // hook in pre-parse listeners +
  19066. // allow xml manipulation
  19067. /**
  19068. * A `import.parse.start` event.
  19069. *
  19070. * @event BaseViewer#ImportParseStartEvent
  19071. * @type {ImportParseStartEvent}
  19072. */
  19073. xml = this._emit('import.parse.start', { xml: xml }) || xml;
  19074. let parseResult;
  19075. try {
  19076. parseResult = await this._moddle.fromXML(xml, 'bpmn:Definitions');
  19077. } catch (error) {
  19078. this._emit('import.parse.complete', {
  19079. error
  19080. });
  19081. throw error;
  19082. }
  19083. let definitions = parseResult.rootElement;
  19084. const references = parseResult.references;
  19085. const parseWarnings = parseResult.warnings;
  19086. const elementsById = parseResult.elementsById;
  19087. aggregatedWarnings = aggregatedWarnings.concat(parseWarnings);
  19088. // hook in post parse listeners +
  19089. // allow definitions manipulation
  19090. /**
  19091. * A `import.parse.complete` event.
  19092. *
  19093. * @event BaseViewer#ImportParseCompleteEvent
  19094. * @type {ImportParseCompleteEvent}
  19095. */
  19096. definitions = this._emit('import.parse.complete', ParseCompleteEvent({
  19097. error: null,
  19098. definitions: definitions,
  19099. elementsById: elementsById,
  19100. references: references,
  19101. warnings: aggregatedWarnings
  19102. })) || definitions;
  19103. const importResult = await this.importDefinitions(definitions, bpmnDiagram);
  19104. aggregatedWarnings = aggregatedWarnings.concat(importResult.warnings);
  19105. /**
  19106. * A `import.parse.complete` event.
  19107. *
  19108. * @event BaseViewer#ImportDoneEvent
  19109. * @type {ImportDoneEvent}
  19110. */
  19111. this._emit('import.done', { error: null, warnings: aggregatedWarnings });
  19112. return { warnings: aggregatedWarnings };
  19113. } catch (err) {
  19114. let error = err;
  19115. aggregatedWarnings = aggregatedWarnings.concat(error.warnings || []);
  19116. addWarningsToError(error, aggregatedWarnings);
  19117. error = checkValidationError(error);
  19118. this._emit('import.done', { error, warnings: error.warnings });
  19119. throw error;
  19120. }
  19121. };
  19122. /**
  19123. * Import parsed definitions and render a BPMN 2.0 diagram.
  19124. *
  19125. * Once finished the viewer reports back the result to the
  19126. * provided callback function with (err, warnings).
  19127. *
  19128. * ## Life-Cycle Events
  19129. *
  19130. * During import the viewer will fire life-cycle events:
  19131. *
  19132. * * import.render.start (graphical import start)
  19133. * * import.render.complete (graphical import finished)
  19134. *
  19135. * You can use these events to hook into the life-cycle.
  19136. *
  19137. * @throws {ImportDefinitionsError} An error thrown during the import of the definitions.
  19138. *
  19139. * @param {ModdleElement} definitions The definitions.
  19140. * @param {ModdleElement|string} [bpmnDiagram] The optional diagram or ID of the BPMN diagram to open.
  19141. *
  19142. * @return {Promise<ImportDefinitionsResult>} A promise resolving with warnings that were produced during the import.
  19143. */
  19144. BaseViewer.prototype.importDefinitions = async function importDefinitions(definitions, bpmnDiagram) {
  19145. this._setDefinitions(definitions);
  19146. const result = await this.open(bpmnDiagram);
  19147. return { warnings: result.warnings };
  19148. };
  19149. /**
  19150. * Open diagram of previously imported XML.
  19151. *
  19152. * Once finished the viewer reports back the result to the
  19153. * provided callback function with (err, warnings).
  19154. *
  19155. * ## Life-Cycle Events
  19156. *
  19157. * During switch the viewer will fire life-cycle events:
  19158. *
  19159. * * import.render.start (graphical import start)
  19160. * * import.render.complete (graphical import finished)
  19161. *
  19162. * You can use these events to hook into the life-cycle.
  19163. *
  19164. * @throws {OpenError} An error thrown during opening.
  19165. *
  19166. * @param {ModdleElement|string} bpmnDiagramOrId The diagram or Id of the BPMN diagram to open.
  19167. *
  19168. * @return {Promise<OpenResult>} A promise resolving with warnings that were produced during opening.
  19169. */
  19170. BaseViewer.prototype.open = async function open(bpmnDiagramOrId) {
  19171. const definitions = this._definitions;
  19172. let bpmnDiagram = bpmnDiagramOrId;
  19173. if (!definitions) {
  19174. const error = new Error('no XML imported');
  19175. addWarningsToError(error, []);
  19176. throw error;
  19177. }
  19178. if (typeof bpmnDiagramOrId === 'string') {
  19179. bpmnDiagram = findBPMNDiagram(definitions, bpmnDiagramOrId);
  19180. if (!bpmnDiagram) {
  19181. const error = new Error('BPMNDiagram <' + bpmnDiagramOrId + '> not found');
  19182. addWarningsToError(error, []);
  19183. throw error;
  19184. }
  19185. }
  19186. // clear existing rendered diagram
  19187. // catch synchronous exceptions during #clear()
  19188. try {
  19189. this.clear();
  19190. } catch (error) {
  19191. addWarningsToError(error, []);
  19192. throw error;
  19193. }
  19194. // perform graphical import
  19195. const { warnings } = await importBpmnDiagram(this, definitions, bpmnDiagram);
  19196. return { warnings };
  19197. };
  19198. /**
  19199. * Export the currently displayed BPMN 2.0 diagram as
  19200. * a BPMN 2.0 XML document.
  19201. *
  19202. * ## Life-Cycle Events
  19203. *
  19204. * During XML saving the viewer will fire life-cycle events:
  19205. *
  19206. * * saveXML.start (before serialization)
  19207. * * saveXML.serialized (after xml generation)
  19208. * * saveXML.done (everything done)
  19209. *
  19210. * You can use these events to hook into the life-cycle.
  19211. *
  19212. * @throws {Error} An error thrown during export.
  19213. *
  19214. * @fires BaseViewer#SaveXMLStart
  19215. * @fires BaseViewer#SaveXMLDone
  19216. *
  19217. * @param {SaveXMLOptions} [options] The options.
  19218. *
  19219. * @return {Promise<SaveXMLResult>} A promise resolving with the XML.
  19220. */
  19221. BaseViewer.prototype.saveXML = async function saveXML(options) {
  19222. options = options || {};
  19223. let definitions = this._definitions,
  19224. error, xml;
  19225. try {
  19226. if (!definitions) {
  19227. throw new Error('no definitions loaded');
  19228. }
  19229. // allow to fiddle around with definitions
  19230. /**
  19231. * A `saveXML.start` event.
  19232. *
  19233. * @event BaseViewer#SaveXMLStartEvent
  19234. * @type {SaveXMLStartEvent}
  19235. */
  19236. definitions = this._emit('saveXML.start', {
  19237. definitions
  19238. }) || definitions;
  19239. const result = await this._moddle.toXML(definitions, options);
  19240. xml = result.xml;
  19241. xml = this._emit('saveXML.serialized', {
  19242. xml
  19243. }) || xml;
  19244. } catch (err) {
  19245. error = err;
  19246. }
  19247. const result = error ? { error } : { xml };
  19248. /**
  19249. * A `saveXML.done` event.
  19250. *
  19251. * @event BaseViewer#SaveXMLDoneEvent
  19252. * @type {SaveXMLDoneEvent}
  19253. */
  19254. this._emit('saveXML.done', result);
  19255. if (error) {
  19256. throw error;
  19257. }
  19258. return result;
  19259. };
  19260. /**
  19261. * Export the currently displayed BPMN 2.0 diagram as
  19262. * an SVG image.
  19263. *
  19264. * ## Life-Cycle Events
  19265. *
  19266. * During SVG saving the viewer will fire life-cycle events:
  19267. *
  19268. * * saveSVG.start (before serialization)
  19269. * * saveSVG.done (everything done)
  19270. *
  19271. * You can use these events to hook into the life-cycle.
  19272. *
  19273. * @throws {Error} An error thrown during export.
  19274. *
  19275. * @fires BaseViewer#SaveSVGDone
  19276. *
  19277. * @return {Promise<SaveSVGResult>} A promise resolving with the SVG.
  19278. */
  19279. BaseViewer.prototype.saveSVG = async function saveSVG() {
  19280. this._emit('saveSVG.start');
  19281. let svg, err;
  19282. try {
  19283. const canvas = this.get('canvas');
  19284. const contentNode = canvas.getActiveLayer(),
  19285. defsNode = query('defs', canvas._svg);
  19286. const contents = innerSVG(contentNode),
  19287. defs = defsNode ? '<defs>' + innerSVG(defsNode) + '</defs>' : '';
  19288. const bbox = contentNode.getBBox();
  19289. svg =
  19290. '<?xml version="1.0" encoding="utf-8"?>\n' +
  19291. '<!-- created with bpmn-js / http://bpmn.io -->\n' +
  19292. '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
  19293. '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ' +
  19294. 'width="' + bbox.width + '" height="' + bbox.height + '" ' +
  19295. 'viewBox="' + bbox.x + ' ' + bbox.y + ' ' + bbox.width + ' ' + bbox.height + '" version="1.1">' +
  19296. defs + contents +
  19297. '</svg>';
  19298. } catch (e) {
  19299. err = e;
  19300. }
  19301. /**
  19302. * A `saveSVG.done` event.
  19303. *
  19304. * @event BaseViewer#SaveSVGDoneEvent
  19305. * @type {SaveSVGDoneEvent}
  19306. */
  19307. this._emit('saveSVG.done', {
  19308. error: err,
  19309. svg: svg
  19310. });
  19311. if (err) {
  19312. throw err;
  19313. }
  19314. return { svg };
  19315. };
  19316. BaseViewer.prototype._setDefinitions = function(definitions) {
  19317. this._definitions = definitions;
  19318. };
  19319. /**
  19320. * Return modules to instantiate with.
  19321. *
  19322. * @return {ModuleDeclaration[]} The modules.
  19323. */
  19324. BaseViewer.prototype.getModules = function() {
  19325. return this._modules;
  19326. };
  19327. /**
  19328. * Remove all drawn elements from the viewer.
  19329. *
  19330. * After calling this method the viewer can still be reused for opening another
  19331. * diagram.
  19332. */
  19333. BaseViewer.prototype.clear = function() {
  19334. if (!this.getDefinitions()) {
  19335. // no diagram to clear
  19336. return;
  19337. }
  19338. // remove drawn elements
  19339. Diagram.prototype.clear.call(this);
  19340. };
  19341. /**
  19342. * Destroy the viewer instance and remove all its remainders from the document
  19343. * tree.
  19344. */
  19345. BaseViewer.prototype.destroy = function() {
  19346. // diagram destroy
  19347. Diagram.prototype.destroy.call(this);
  19348. // dom detach
  19349. remove$1(this._container);
  19350. };
  19351. /**
  19352. * Register an event listener.
  19353. *
  19354. * Remove an event listener via {@link BaseViewer#off}.
  19355. *
  19356. * @template T
  19357. *
  19358. * @param {string|string[]} events The event(s) to listen to.
  19359. * @param {number} [priority] The priority with which to listen.
  19360. * @param {EventBusEventCallback<T>} callback The callback.
  19361. * @param {any} [that] Value of `this` the callback will be called with.
  19362. */
  19363. BaseViewer.prototype.on = function(events, priority, callback, that) {
  19364. return this.get('eventBus').on(events, priority, callback, that);
  19365. };
  19366. /**
  19367. * Remove an event listener.
  19368. *
  19369. * @param {string|string[]} events The event(s).
  19370. * @param {Function} [callback] The callback.
  19371. */
  19372. BaseViewer.prototype.off = function(events, callback) {
  19373. this.get('eventBus').off(events, callback);
  19374. };
  19375. /**
  19376. * Attach the viewer to an HTML element.
  19377. *
  19378. * @param {HTMLElement} parentNode The parent node to attach to.
  19379. */
  19380. BaseViewer.prototype.attachTo = function(parentNode) {
  19381. if (!parentNode) {
  19382. throw new Error('parentNode required');
  19383. }
  19384. // ensure we detach from the
  19385. // previous, old parent
  19386. this.detach();
  19387. // unwrap jQuery if provided
  19388. if (parentNode.get && parentNode.constructor.prototype.jquery) {
  19389. parentNode = parentNode.get(0);
  19390. }
  19391. if (typeof parentNode === 'string') {
  19392. parentNode = query(parentNode);
  19393. }
  19394. parentNode.appendChild(this._container);
  19395. this._emit('attach', {});
  19396. this.get('canvas').resized();
  19397. };
  19398. /**
  19399. * Get the definitions model element.
  19400. *
  19401. * @return {ModdleElement} The definitions model element.
  19402. */
  19403. BaseViewer.prototype.getDefinitions = function() {
  19404. return this._definitions;
  19405. };
  19406. /**
  19407. * Detach the viewer.
  19408. *
  19409. * @fires BaseViewer#DetachEvent
  19410. */
  19411. BaseViewer.prototype.detach = function() {
  19412. const container = this._container,
  19413. parentNode = container.parentNode;
  19414. if (!parentNode) {
  19415. return;
  19416. }
  19417. /**
  19418. * A `detach` event.
  19419. *
  19420. * @event BaseViewer#DetachEvent
  19421. * @type {Object}
  19422. */
  19423. this._emit('detach', {});
  19424. parentNode.removeChild(container);
  19425. };
  19426. BaseViewer.prototype._init = function(container, moddle, options) {
  19427. const baseModules = options.modules || this.getModules(options),
  19428. additionalModules = options.additionalModules || [],
  19429. staticModules = [
  19430. {
  19431. bpmnjs: [ 'value', this ],
  19432. moddle: [ 'value', moddle ]
  19433. }
  19434. ];
  19435. const diagramModules = [].concat(staticModules, baseModules, additionalModules);
  19436. const diagramOptions = assign$1(omit(options, [ 'additionalModules' ]), {
  19437. canvas: assign$1({}, options.canvas, { container: container }),
  19438. modules: diagramModules
  19439. });
  19440. // invoke diagram constructor
  19441. Diagram.call(this, diagramOptions);
  19442. if (options && options.container) {
  19443. this.attachTo(options.container);
  19444. }
  19445. };
  19446. /**
  19447. * Emit an event on the underlying {@link EventBus}
  19448. *
  19449. * @param {string} type
  19450. * @param {Object} event
  19451. *
  19452. * @return {Object} The return value after calling all event listeners.
  19453. */
  19454. BaseViewer.prototype._emit = function(type, event) {
  19455. return this.get('eventBus').fire(type, event);
  19456. };
  19457. /**
  19458. * @param {BaseViewerOptions} options
  19459. *
  19460. * @return {HTMLElement}
  19461. */
  19462. BaseViewer.prototype._createContainer = function(options) {
  19463. const container = domify$1('<div class="bjs-container"></div>');
  19464. assign(container, {
  19465. width: ensureUnit(options.width),
  19466. height: ensureUnit(options.height),
  19467. position: options.position
  19468. });
  19469. return container;
  19470. };
  19471. /**
  19472. * @param {BaseViewerOptions} options
  19473. *
  19474. * @return {Moddle}
  19475. */
  19476. BaseViewer.prototype._createModdle = function(options) {
  19477. const moddleOptions = assign$1({}, this._moddleExtensions, options.moddleExtensions);
  19478. return new simple(moddleOptions);
  19479. };
  19480. BaseViewer.prototype._modules = [];
  19481. // helpers ///////////////
  19482. function addWarningsToError(err, warningsAry) {
  19483. err.warnings = warningsAry;
  19484. return err;
  19485. }
  19486. function checkValidationError(err) {
  19487. // check if we can help the user by indicating wrong BPMN 2.0 xml
  19488. // (in case he or the exporting tool did not get that right)
  19489. const pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/;
  19490. const match = pattern.exec(err.message);
  19491. if (match) {
  19492. err.message =
  19493. 'unparsable content <' + match[1] + '> detected; ' +
  19494. 'this may indicate an invalid BPMN 2.0 diagram file' + match[2];
  19495. }
  19496. return err;
  19497. }
  19498. const DEFAULT_OPTIONS = {
  19499. width: '100%',
  19500. height: '100%',
  19501. position: 'relative'
  19502. };
  19503. /**
  19504. * Ensure the passed argument is a proper unit (defaulting to px)
  19505. */
  19506. function ensureUnit(val) {
  19507. return val + (isNumber(val) ? 'px' : '');
  19508. }
  19509. /**
  19510. * Find BPMNDiagram in definitions by ID
  19511. *
  19512. * @param {ModdleElement<Definitions>} definitions
  19513. * @param {string} diagramId
  19514. *
  19515. * @return {ModdleElement<BPMNDiagram>|null}
  19516. */
  19517. function findBPMNDiagram(definitions, diagramId) {
  19518. if (!diagramId) {
  19519. return null;
  19520. }
  19521. return find(definitions.diagrams, function(element) {
  19522. return element.id === diagramId;
  19523. }) || null;
  19524. }
  19525. /**
  19526. * Adds the project logo to the diagram container as
  19527. * required by the bpmn.io license.
  19528. *
  19529. * @see http://bpmn.io/license
  19530. *
  19531. * @param {Element} container
  19532. */
  19533. function addProjectLogo(container) {
  19534. const img = BPMNIO_IMG;
  19535. const linkMarkup =
  19536. '<a href="http://bpmn.io" ' +
  19537. 'target="_blank" ' +
  19538. 'class="bjs-powered-by" ' +
  19539. 'title="Powered by bpmn.io" ' +
  19540. '>' +
  19541. img +
  19542. '</a>';
  19543. const linkElement = domify$1(linkMarkup);
  19544. assign(query('svg', linkElement), LOGO_STYLES);
  19545. assign(linkElement, LINK_STYLES, {
  19546. position: 'absolute',
  19547. bottom: '15px',
  19548. right: '15px',
  19549. zIndex: '100'
  19550. });
  19551. container.appendChild(linkElement);
  19552. event.bind(linkElement, 'click', function(event) {
  19553. open();
  19554. event.preventDefault();
  19555. });
  19556. }
  19557. /* </project-logo> */
  19558. /**
  19559. * @typedef { import('./BaseViewer').BaseViewerOptions } BaseViewerOptions
  19560. */
  19561. /**
  19562. * A viewer for BPMN 2.0 diagrams.
  19563. *
  19564. * Have a look at {@link NavigatedViewer} or {@link Modeler} for bundles that include
  19565. * additional features.
  19566. *
  19567. *
  19568. * ## Extending the Viewer
  19569. *
  19570. * In order to extend the viewer pass extension modules to bootstrap via the
  19571. * `additionalModules` option. An extension module is an object that exposes
  19572. * named services.
  19573. *
  19574. * The following example depicts the integration of a simple
  19575. * logging component that integrates with interaction events:
  19576. *
  19577. *
  19578. * ```javascript
  19579. *
  19580. * // logging component
  19581. * function InteractionLogger(eventBus) {
  19582. * eventBus.on('element.hover', function(event) {
  19583. * console.log()
  19584. * })
  19585. * }
  19586. *
  19587. * InteractionLogger.$inject = [ 'eventBus' ]; // minification save
  19588. *
  19589. * // extension module
  19590. * var extensionModule = {
  19591. * __init__: [ 'interactionLogger' ],
  19592. * interactionLogger: [ 'type', InteractionLogger ]
  19593. * };
  19594. *
  19595. * // extend the viewer
  19596. * var bpmnViewer = new Viewer({ additionalModules: [ extensionModule ] });
  19597. * bpmnViewer.importXML(...);
  19598. * ```
  19599. *
  19600. * @param {BaseViewerOptions} [options] The options to configure the viewer.
  19601. */
  19602. function Viewer(options) {
  19603. BaseViewer.call(this, options);
  19604. }
  19605. e(Viewer, BaseViewer);
  19606. // modules the viewer is composed of
  19607. Viewer.prototype._modules = [
  19608. CoreModule$1,
  19609. TranslateModule,
  19610. SelectionModule,
  19611. OverlaysModule,
  19612. DrilldownModdule
  19613. ];
  19614. // default moddle extensions the viewer is composed of
  19615. Viewer.prototype._moddleExtensions = {};
  19616. return Viewer;
  19617. }));