kityminder.core.js 370 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358
  1. /*!
  2. * ====================================================
  3. * Kity Minder Core - v1.4.50 - 2018-09-17
  4. * https://github.com/fex-team/kityminder-core
  5. * GitHub: https://github.com/fex-team/kityminder-core.git
  6. * Copyright (c) 2018 Baidu FEX; Licensed BSD-3-Clause
  7. * ====================================================
  8. */
  9. (function () {
  10. var _p = {
  11. r: function(index) {
  12. if (_p[index].inited) {
  13. return _p[index].value;
  14. }
  15. if (typeof _p[index].value === "function") {
  16. var module = {
  17. exports: {}
  18. }, returnValue = _p[index].value(null, module.exports, module);
  19. _p[index].inited = true;
  20. _p[index].value = returnValue;
  21. if (returnValue !== undefined) {
  22. return returnValue;
  23. } else {
  24. for (var key in module.exports) {
  25. if (module.exports.hasOwnProperty(key)) {
  26. _p[index].inited = true;
  27. _p[index].value = module.exports;
  28. return module.exports;
  29. }
  30. }
  31. }
  32. } else {
  33. _p[index].inited = true;
  34. return _p[index].value;
  35. }
  36. }
  37. };
  38. //src/connect/arc.js
  39. /**
  40. * @fileOverview
  41. *
  42. * 圆弧连线
  43. *
  44. * @author: techird
  45. * @copyright: Baidu FEX, 2014
  46. */
  47. _p[0] = {
  48. value: function(require, exports, module) {
  49. var kity = _p.r(17);
  50. var connect = _p.r(11);
  51. var connectMarker = new kity.Marker().pipe(function() {
  52. var r = 7;
  53. var dot = new kity.Circle(r - 1);
  54. this.addShape(dot);
  55. this.setRef(r - 1, 0).setViewBox(-r, -r, r + r, r + r).setWidth(r).setHeight(r);
  56. this.dot = dot;
  57. this.node.setAttribute("markerUnits", "userSpaceOnUse");
  58. });
  59. connect.register("arc", function(node, parent, connection, width, color) {
  60. var box = node.getLayoutBox(), pBox = parent.getLayoutBox();
  61. var start, end, vector;
  62. var abs = Math.abs;
  63. var pathData = [];
  64. var side = box.x > pBox.x ? "right" : "left";
  65. node.getMinder().getPaper().addResource(connectMarker);
  66. start = new kity.Point(pBox.cx, pBox.cy);
  67. end = side == "left" ? new kity.Point(box.right + 2, box.cy) : new kity.Point(box.left - 2, box.cy);
  68. vector = kity.Vector.fromPoints(start, end);
  69. pathData.push("M", start);
  70. pathData.push("A", abs(vector.x), abs(vector.y), 0, 0, vector.x * vector.y > 0 ? 0 : 1, end);
  71. connection.setMarker(connectMarker);
  72. connectMarker.dot.fill(color);
  73. connection.setPathData(pathData);
  74. });
  75. }
  76. };
  77. //src/connect/arc_tp.js
  78. /**
  79. *
  80. * 圆弧连线
  81. *
  82. * @author: along
  83. * @copyright: bpd729@163.com , 2015
  84. */
  85. _p[1] = {
  86. value: function(require, exports, module) {
  87. var kity = _p.r(17);
  88. var connect = _p.r(11);
  89. var connectMarker = new kity.Marker().pipe(function() {
  90. var r = 7;
  91. var dot = new kity.Circle(r - 1);
  92. this.addShape(dot);
  93. this.setRef(r - 1, 0).setViewBox(-r, -r, r + r, r + r).setWidth(r).setHeight(r);
  94. this.dot = dot;
  95. this.node.setAttribute("markerUnits", "userSpaceOnUse");
  96. });
  97. /**
  98. * 天盘图连线除了连接当前节点和前一个节点外, 还需要渲染当前节点和后一个节点的连接, 防止样式上的断线
  99. * 这是天盘图与其余的模板不同的地方
  100. */
  101. connect.register("arc_tp", function(node, parent, connection, width, color) {
  102. var end_box = node.getLayoutBox(), start_box = parent.getLayoutBox();
  103. var index = node.getIndex();
  104. var nextNode = parent.getChildren()[index + 1];
  105. if (node.getIndex() > 0) {
  106. start_box = parent.getChildren()[index - 1].getLayoutBox();
  107. }
  108. var start, end, vector;
  109. var abs = Math.abs;
  110. var pathData = [];
  111. var side = end_box.x > start_box.x ? "right" : "left";
  112. node.getMinder().getPaper().addResource(connectMarker);
  113. start = new kity.Point(start_box.cx, start_box.cy);
  114. end = new kity.Point(end_box.cx, end_box.cy);
  115. var jl = Math.sqrt(Math.pow(start.x - end.x, 2) + Math.pow(start.y - end.y, 2));
  116. //两圆中心点距离
  117. jl = node.getIndex() == 0 ? jl * .4 : jl;
  118. vector = kity.Vector.fromPoints(start, end);
  119. pathData.push("M", start);
  120. pathData.push("A", jl, jl, 0, 0, 1, end);
  121. connection.setMarker(connectMarker);
  122. connectMarker.dot.fill(color);
  123. connection.setPathData(pathData);
  124. // 设置下一个的节点的连接线
  125. if (nextNode && nextNode.getConnection()) {
  126. var nextConnection = nextNode.getConnection();
  127. var next_end_box = nextNode.getLayoutBox();
  128. var next_end = new kity.Point(next_end_box.cx, next_end_box.cy);
  129. var jl2 = Math.sqrt(Math.pow(end.x - next_end.x, 2) + Math.pow(end.y - next_end.y, 2));
  130. //两圆中心点距离
  131. pathData = [];
  132. pathData.push("M", end);
  133. pathData.push("A", jl2, jl2, 0, 0, 1, next_end);
  134. nextConnection.setMarker(connectMarker);
  135. connectMarker.dot.fill(color);
  136. nextConnection.setPathData(pathData);
  137. }
  138. });
  139. }
  140. };
  141. //src/connect/bezier.js
  142. /**
  143. * @fileOverview
  144. *
  145. * 提供折线相连的方法
  146. *
  147. * @author: techird
  148. * @copyright: Baidu FEX, 2014
  149. */
  150. _p[2] = {
  151. value: function(require, exports, module) {
  152. var kity = _p.r(17);
  153. var connect = _p.r(11);
  154. connect.register("bezier", function(node, parent, connection) {
  155. // 连线起点和终点
  156. var po = parent.getLayoutVertexOut(), pi = node.getLayoutVertexIn();
  157. // 连线矢量和方向
  158. var v = parent.getLayoutVectorOut().normalize();
  159. var r = Math.round;
  160. var abs = Math.abs;
  161. var pathData = [];
  162. pathData.push("M", r(po.x), r(po.y));
  163. if (abs(v.x) > abs(v.y)) {
  164. // x - direction
  165. var hx = (pi.x + po.x) / 2;
  166. pathData.push("C", hx, po.y, hx, pi.y, pi.x, pi.y);
  167. } else {
  168. // y - direction
  169. var hy = (pi.y + po.y) / 2;
  170. pathData.push("C", po.x, hy, pi.x, hy, pi.x, pi.y);
  171. }
  172. connection.setMarker(null);
  173. connection.setPathData(pathData);
  174. });
  175. }
  176. };
  177. //src/connect/fish-bone-master.js
  178. /**
  179. * @fileOverview
  180. *
  181. * 鱼骨头主干连线
  182. *
  183. * @author: techird
  184. * @copyright: Baidu FEX, 2014
  185. */
  186. _p[3] = {
  187. value: function(require, exports, module) {
  188. var kity = _p.r(17);
  189. var connect = _p.r(11);
  190. connect.register("fish-bone-master", function(node, parent, connection) {
  191. var pout = parent.getLayoutVertexOut(), pin = node.getLayoutVertexIn();
  192. var abs = Math.abs;
  193. var dy = abs(pout.y - pin.y), dx = abs(pout.x - pin.x);
  194. var pathData = [];
  195. pathData.push("M", pout.x, pout.y);
  196. pathData.push("h", dx - dy);
  197. pathData.push("L", pin.x, pin.y);
  198. connection.setMarker(null);
  199. connection.setPathData(pathData);
  200. });
  201. }
  202. };
  203. //src/connect/l.js
  204. /**
  205. * @fileOverview
  206. *
  207. * "L" 连线
  208. *
  209. * @author: techird
  210. * @copyright: Baidu FEX, 2014
  211. */
  212. _p[4] = {
  213. value: function(require, exports, module) {
  214. var kity = _p.r(17);
  215. var connect = _p.r(11);
  216. connect.register("l", function(node, parent, connection) {
  217. var po = parent.getLayoutVertexOut();
  218. var pi = node.getLayoutVertexIn();
  219. var vo = parent.getLayoutVectorOut();
  220. var pathData = [];
  221. var r = Math.round, abs = Math.abs;
  222. pathData.push("M", po.round());
  223. if (abs(vo.x) > abs(vo.y)) {
  224. pathData.push("H", r(pi.x));
  225. } else {
  226. pathData.push("V", pi.y);
  227. }
  228. pathData.push("L", pi);
  229. connection.setPathData(pathData);
  230. });
  231. }
  232. };
  233. //src/connect/poly.js
  234. /**
  235. * @fileOverview
  236. *
  237. * 提供折线相连的方法
  238. *
  239. * @author: techird
  240. * @copyright: Baidu FEX, 2014
  241. */
  242. _p[5] = {
  243. value: function(require, exports, module) {
  244. var kity = _p.r(17);
  245. var connect = _p.r(11);
  246. connect.register("poly", function(node, parent, connection, width) {
  247. // 连线起点和终点
  248. var po = parent.getLayoutVertexOut(), pi = node.getLayoutVertexIn();
  249. // 连线矢量和方向
  250. var v = parent.getLayoutVectorOut().normalize();
  251. var r = Math.round;
  252. var abs = Math.abs;
  253. var pathData = [];
  254. pathData.push("M", r(po.x), r(po.y));
  255. switch (true) {
  256. case abs(v.x) > abs(v.y) && v.x < 0:
  257. // left
  258. pathData.push("h", -parent.getStyle("margin-left"));
  259. pathData.push("v", pi.y - po.y);
  260. pathData.push("H", pi.x);
  261. break;
  262. case abs(v.x) > abs(v.y) && v.x >= 0:
  263. // right
  264. pathData.push("h", parent.getStyle("margin-right"));
  265. pathData.push("v", pi.y - po.y);
  266. pathData.push("H", pi.x);
  267. break;
  268. case abs(v.x) <= abs(v.y) && v.y < 0:
  269. // top
  270. pathData.push("v", -parent.getStyle("margin-top"));
  271. pathData.push("h", pi.x - po.x);
  272. pathData.push("V", pi.y);
  273. break;
  274. case abs(v.x) <= abs(v.y) && v.y >= 0:
  275. // bottom
  276. pathData.push("v", parent.getStyle("margin-bottom"));
  277. pathData.push("h", pi.x - po.x);
  278. pathData.push("V", pi.y);
  279. break;
  280. }
  281. connection.setMarker(null);
  282. connection.setPathData(pathData);
  283. });
  284. }
  285. };
  286. //src/connect/under.js
  287. /**
  288. * @fileOverview
  289. *
  290. * 下划线连线
  291. *
  292. * @author: techird
  293. * @copyright: Baidu FEX, 2014
  294. */
  295. _p[6] = {
  296. value: function(require, exports, module) {
  297. var kity = _p.r(17);
  298. var connect = _p.r(11);
  299. connect.register("under", function(node, parent, connection, width, color) {
  300. var box = node.getLayoutBox(), pBox = parent.getLayoutBox();
  301. var start, end, vector;
  302. var abs = Math.abs;
  303. var pathData = [];
  304. var side = box.x > pBox.x ? "right" : "left";
  305. var radius = node.getStyle("connect-radius");
  306. var underY = box.bottom + 3;
  307. var startY = parent.getType() == "sub" ? pBox.bottom + 3 : pBox.cy;
  308. var p1, p2, p3, mx;
  309. if (side == "right") {
  310. p1 = new kity.Point(pBox.right, startY);
  311. p2 = new kity.Point(box.left - 10, underY);
  312. p3 = new kity.Point(box.right, underY);
  313. } else {
  314. p1 = new kity.Point(pBox.left, startY);
  315. p2 = new kity.Point(box.right + 10, underY);
  316. p3 = new kity.Point(box.left, underY);
  317. }
  318. mx = (p1.x + p2.x) / 2;
  319. pathData.push("M", p1);
  320. pathData.push("C", mx, p1.y, mx, p2.y, p2);
  321. pathData.push("L", p3);
  322. connection.setMarker(null);
  323. connection.setPathData(pathData);
  324. });
  325. }
  326. };
  327. //src/core/_boxv.js
  328. /**
  329. * @fileOverview
  330. *
  331. * 调试工具:为 kity.Box 提供一个可视化的渲染
  332. *
  333. * @author: techird
  334. * @copyright: Baidu FEX, 2014
  335. */
  336. _p[7] = {
  337. value: function(require, exports, module) {
  338. var kity = _p.r(17);
  339. var Minder = _p.r(19);
  340. if (location.href.indexOf("boxv") != -1) {
  341. var vrect;
  342. Object.defineProperty(kity.Box.prototype, "visualization", {
  343. get: function() {
  344. if (!vrect) return null;
  345. return vrect.setBox(this);
  346. }
  347. });
  348. Minder.registerInitHook(function() {
  349. this.on("paperrender", function() {
  350. vrect = new kity.Rect();
  351. vrect.fill("rgba(200, 200, 200, .5)");
  352. vrect.stroke("orange");
  353. this.getRenderContainer().addShape(vrect);
  354. });
  355. });
  356. }
  357. }
  358. };
  359. //src/core/animate.js
  360. /**
  361. * @fileOverview
  362. *
  363. * 动画控制
  364. *
  365. * @author: techird
  366. * @copyright: Baidu FEX, 2014
  367. */
  368. _p[8] = {
  369. value: function(require, exports, module) {
  370. var Minder = _p.r(19);
  371. var animateDefaultOptions = {
  372. enableAnimation: true,
  373. layoutAnimationDuration: 300,
  374. viewAnimationDuration: 100,
  375. zoomAnimationDuration: 300
  376. };
  377. var resoredAnimationOptions = {};
  378. Minder.registerInitHook(function() {
  379. this.setDefaultOptions(animateDefaultOptions);
  380. if (!this.getOption("enableAnimation")) {
  381. this.disableAnimation();
  382. }
  383. });
  384. Minder.prototype.enableAnimation = function() {
  385. for (var name in animateDefaultOptions) {
  386. if (animateDefaultOptions.hasOwnProperty(name)) {
  387. this.setOption(resoredAnimationOptions[name]);
  388. }
  389. }
  390. };
  391. Minder.prototype.disableAnimation = function() {
  392. for (var name in animateDefaultOptions) {
  393. if (animateDefaultOptions.hasOwnProperty(name)) {
  394. resoredAnimationOptions[name] = this.getOption(name);
  395. this.setOption(name, 0);
  396. }
  397. }
  398. };
  399. }
  400. };
  401. //src/core/command.js
  402. _p[9] = {
  403. value: function(require, exports, module) {
  404. var kity = _p.r(17);
  405. var utils = _p.r(33);
  406. var Minder = _p.r(19);
  407. var MinderNode = _p.r(21);
  408. var MinderEvent = _p.r(13);
  409. var COMMAND_STATE_NORMAL = 0;
  410. var COMMAND_STATE_DISABLED = -1;
  411. var COMMAND_STATE_ACTIVED = 1;
  412. /**
  413. * 表示一个命令,包含命令的查询及执行
  414. */
  415. var Command = kity.createClass("Command", {
  416. constructor: function() {
  417. this._isContentChange = true;
  418. this._isSelectionChange = false;
  419. },
  420. execute: function(minder, args) {
  421. throw new Error("Not Implement: Command.execute()");
  422. },
  423. setContentChanged: function(val) {
  424. this._isContentChange = !!val;
  425. },
  426. isContentChanged: function() {
  427. return this._isContentChange;
  428. },
  429. setSelectionChanged: function(val) {
  430. this._isSelectionChange = !!val;
  431. },
  432. isSelectionChanged: function() {
  433. return this._isContentChange;
  434. },
  435. queryState: function(km) {
  436. return COMMAND_STATE_NORMAL;
  437. },
  438. queryValue: function(km) {
  439. return 0;
  440. },
  441. isNeedUndo: function() {
  442. return true;
  443. }
  444. });
  445. Command.STATE_NORMAL = COMMAND_STATE_NORMAL;
  446. Command.STATE_ACTIVE = COMMAND_STATE_ACTIVED;
  447. Command.STATE_DISABLED = COMMAND_STATE_DISABLED;
  448. kity.extendClass(Minder, {
  449. _getCommand: function(name) {
  450. return this._commands[name.toLowerCase()];
  451. },
  452. _queryCommand: function(name, type, args) {
  453. var cmd = this._getCommand(name);
  454. if (cmd) {
  455. var queryCmd = cmd["query" + type];
  456. if (queryCmd) return queryCmd.apply(cmd, [ this ].concat(args));
  457. }
  458. return 0;
  459. },
  460. /**
  461. * @method queryCommandState()
  462. * @for Minder
  463. * @description 查询指定命令的状态
  464. *
  465. * @grammar queryCommandName(name) => {number}
  466. *
  467. * @param {string} name 要查询的命令名称
  468. *
  469. * @return {number}
  470. * -1: 命令不存在或命令当前不可用
  471. * 0: 命令可用
  472. * 1: 命令当前可用并且已经执行过
  473. */
  474. queryCommandState: function(name) {
  475. return this._queryCommand(name, "State", [].slice.call(arguments, 1));
  476. },
  477. /**
  478. * @method queryCommandValue()
  479. * @for Minder
  480. * @description 查询指定命令当前的执行值
  481. *
  482. * @grammar queryCommandValue(name) => {any}
  483. *
  484. * @param {string} name 要查询的命令名称
  485. *
  486. * @return {any}
  487. * 如果命令不存在,返回 undefined
  488. * 不同命令具有不同返回值,具体请查看 [Command](command) 章节
  489. */
  490. queryCommandValue: function(name) {
  491. return this._queryCommand(name, "Value", [].slice.call(arguments, 1));
  492. },
  493. /**
  494. * @method execCommand()
  495. * @for Minder
  496. * @description 执行指定的命令。
  497. *
  498. * @grammar execCommand(name, args...)
  499. *
  500. * @param {string} name 要执行的命令名称
  501. * @param {argument} args 要传递给命令的其它参数
  502. */
  503. execCommand: function(name) {
  504. if (!name) return null;
  505. name = name.toLowerCase();
  506. var cmdArgs = [].slice.call(arguments, 1), cmd, stoped, result, eventParams;
  507. var me = this;
  508. cmd = this._getCommand(name);
  509. eventParams = {
  510. command: cmd,
  511. commandName: name.toLowerCase(),
  512. commandArgs: cmdArgs
  513. };
  514. if (!cmd || !~this.queryCommandState(name)) {
  515. return false;
  516. }
  517. if (!this._hasEnterExecCommand) {
  518. this._hasEnterExecCommand = true;
  519. stoped = this._fire(new MinderEvent("beforeExecCommand", eventParams, true));
  520. if (!stoped) {
  521. this._fire(new MinderEvent("preExecCommand", eventParams, false));
  522. result = cmd.execute.apply(cmd, [ me ].concat(cmdArgs));
  523. this._fire(new MinderEvent("execCommand", eventParams, false));
  524. if (cmd.isContentChanged()) {
  525. this._firePharse(new MinderEvent("contentchange"));
  526. }
  527. this._interactChange();
  528. }
  529. this._hasEnterExecCommand = false;
  530. } else {
  531. result = cmd.execute.apply(cmd, [ me ].concat(cmdArgs));
  532. if (!this._hasEnterExecCommand) {
  533. this._interactChange();
  534. }
  535. }
  536. return result === undefined ? null : result;
  537. }
  538. });
  539. module.exports = Command;
  540. }
  541. };
  542. //src/core/compatibility.js
  543. _p[10] = {
  544. value: function(require, exports, module) {
  545. var utils = _p.r(33);
  546. function compatibility(json) {
  547. var version = json.version || (json.root ? "1.4.0" : "1.1.3");
  548. switch (version) {
  549. case "1.1.3":
  550. c_113_120(json);
  551. /* falls through */
  552. case "1.2.0":
  553. case "1.2.1":
  554. c_120_130(json);
  555. /* falls through */
  556. case "1.3.0":
  557. case "1.3.1":
  558. case "1.3.2":
  559. case "1.3.3":
  560. case "1.3.4":
  561. case "1.3.5":
  562. /* falls through */
  563. c_130_140(json);
  564. }
  565. return json;
  566. }
  567. function traverse(node, fn) {
  568. fn(node);
  569. if (node.children) node.children.forEach(function(child) {
  570. traverse(child, fn);
  571. });
  572. }
  573. /* 脑图数据升级 */
  574. function c_120_130(json) {
  575. traverse(json, function(node) {
  576. var data = node.data;
  577. delete data.layout_bottom_offset;
  578. delete data.layout_default_offset;
  579. delete data.layout_filetree_offset;
  580. });
  581. }
  582. /**
  583. * 脑图数据升级
  584. * v1.1.3 => v1.2.0
  585. * */
  586. function c_113_120(json) {
  587. // 原本的布局风格
  588. var ocs = json.data.currentstyle;
  589. delete json.data.currentstyle;
  590. // 为 1.2 选择模板,同时保留老版本文件的皮肤
  591. if (ocs == "bottom") {
  592. json.template = "structure";
  593. json.theme = "snow";
  594. } else if (ocs == "default") {
  595. json.template = "default";
  596. json.theme = "classic";
  597. }
  598. traverse(json, function(node) {
  599. var data = node.data;
  600. // 升级优先级、进度图标
  601. if ("PriorityIcon" in data) {
  602. data.priority = data.PriorityIcon;
  603. delete data.PriorityIcon;
  604. }
  605. if ("ProgressIcon" in data) {
  606. data.progress = 1 + (data.ProgressIcon - 1 << 1);
  607. delete data.ProgressIcon;
  608. }
  609. // 删除过时属性
  610. delete data.point;
  611. delete data.layout;
  612. });
  613. }
  614. function c_130_140(json) {
  615. json.root = {
  616. data: json.data,
  617. children: json.children
  618. };
  619. delete json.data;
  620. delete json.children;
  621. }
  622. return compatibility;
  623. }
  624. };
  625. //src/core/connect.js
  626. _p[11] = {
  627. value: function(require, exports, module) {
  628. var kity = _p.r(17);
  629. var utils = _p.r(33);
  630. var Module = _p.r(20);
  631. var Minder = _p.r(19);
  632. var MinderNode = _p.r(21);
  633. // 连线提供方
  634. var _connectProviders = {};
  635. function register(name, provider) {
  636. _connectProviders[name] = provider;
  637. }
  638. register("default", function(node, parent, connection) {
  639. connection.setPathData([ "M", parent.getLayoutVertexOut(), "L", node.getLayoutVertexIn() ]);
  640. });
  641. kity.extendClass(MinderNode, {
  642. /**
  643. * @private
  644. * @method getConnect()
  645. * @for MinderNode
  646. * @description 获取当前节点的连线类型
  647. *
  648. * @grammar getConnect() => {string}
  649. */
  650. getConnect: function() {
  651. return this.data.connect || "default";
  652. },
  653. getConnectProvider: function() {
  654. return _connectProviders[this.getConnect()] || _connectProviders["default"];
  655. },
  656. /**
  657. * @private
  658. * @method getConnection()
  659. * @for MinderNode
  660. * @description 获取当前节点的连线对象
  661. *
  662. * @grammar getConnection() => {kity.Path}
  663. */
  664. getConnection: function() {
  665. return this._connection || null;
  666. }
  667. });
  668. kity.extendClass(Minder, {
  669. getConnectContainer: function() {
  670. return this._connectContainer;
  671. },
  672. createConnect: function(node) {
  673. if (node.isRoot()) return;
  674. var connection = new kity.Path();
  675. node._connection = connection;
  676. this._connectContainer.addShape(connection);
  677. this.updateConnect(node);
  678. },
  679. removeConnect: function(node) {
  680. var me = this;
  681. node.traverse(function(node) {
  682. me._connectContainer.removeShape(node._connection);
  683. node._connection = null;
  684. });
  685. },
  686. updateConnect: function(node) {
  687. var connection = node._connection;
  688. var parent = node.parent;
  689. if (!parent || !connection) return;
  690. if (parent.isCollapsed()) {
  691. connection.setVisible(false);
  692. return;
  693. }
  694. connection.setVisible(true);
  695. var provider = node.getConnectProvider();
  696. var strokeColor = node.getStyle("connect-color") || "white", strokeWidth = node.getStyle("connect-width") || 2;
  697. connection.stroke(strokeColor, strokeWidth);
  698. provider(node, parent, connection, strokeWidth, strokeColor);
  699. if (strokeWidth % 2 === 0) {
  700. connection.setTranslate(.5, .5);
  701. } else {
  702. connection.setTranslate(0, 0);
  703. }
  704. }
  705. });
  706. Module.register("Connect", {
  707. init: function() {
  708. this._connectContainer = new kity.Group().setId(utils.uuid("minder_connect_group"));
  709. this.getRenderContainer().prependShape(this._connectContainer);
  710. },
  711. events: {
  712. nodeattach: function(e) {
  713. this.createConnect(e.node);
  714. },
  715. nodedetach: function(e) {
  716. this.removeConnect(e.node);
  717. },
  718. "layoutapply layoutfinish noderender": function(e) {
  719. this.updateConnect(e.node);
  720. }
  721. }
  722. });
  723. exports.register = register;
  724. }
  725. };
  726. //src/core/data.js
  727. _p[12] = {
  728. value: function(require, exports, module) {
  729. var kity = _p.r(17);
  730. var utils = _p.r(33);
  731. var Minder = _p.r(19);
  732. var MinderNode = _p.r(21);
  733. var MinderEvent = _p.r(13);
  734. var compatibility = _p.r(10);
  735. var Promise = _p.r(25);
  736. var protocols = {};
  737. function registerProtocol(name, protocol) {
  738. protocols[name] = protocol;
  739. for (var pname in protocols) {
  740. if (protocols.hasOwnProperty(pname)) {
  741. protocols[pname] = protocols[pname];
  742. protocols[pname].name = pname;
  743. }
  744. }
  745. }
  746. function getRegisterProtocol(name) {
  747. return name === undefined ? protocols : protocols[name] || null;
  748. }
  749. exports.registerProtocol = registerProtocol;
  750. exports.getRegisterProtocol = getRegisterProtocol;
  751. // 导入导出
  752. kity.extendClass(Minder, {
  753. // 自动导入
  754. setup: function(target) {
  755. if (typeof target == "string") {
  756. target = document.querySelector(target);
  757. }
  758. if (!target) return;
  759. var protocol = target.getAttribute("minder-data-type");
  760. if (protocol in protocols) {
  761. var data = target.textContent;
  762. target.textContent = null;
  763. this.renderTo(target);
  764. this.importData(protocol, data);
  765. }
  766. return this;
  767. },
  768. /**
  769. * @method exportJson()
  770. * @for Minder
  771. * @description
  772. * 导出当前脑图数据为 JSON 对象,导出的数据格式请参考 [Data](data) 章节。
  773. * @grammar exportJson() => {plain}
  774. */
  775. exportJson: function() {
  776. /* 导出 node 上整棵树的数据为 JSON */
  777. function exportNode(node) {
  778. var exported = {};
  779. exported.data = node.getData();
  780. var childNodes = node.getChildren();
  781. exported.children = [];
  782. for (var i = 0; i < childNodes.length; i++) {
  783. exported.children.push(exportNode(childNodes[i]));
  784. }
  785. return exported;
  786. }
  787. var json = {
  788. root: exportNode(this.getRoot())
  789. };
  790. json.template = this.getTemplate();
  791. json.theme = this.getTheme();
  792. json.version = Minder.version;
  793. return JSON.parse(JSON.stringify(json));
  794. },
  795. /**
  796. * function Text2Children(MinderNode, String)
  797. * @param {MinderNode} node 要导入数据的节点
  798. * @param {String} text 导入的text数据
  799. * @Desc: 用于批量插入子节点,并不会修改被插入的父节点
  800. * @Editor: Naixor
  801. * @Date: 2015.9.21
  802. * @example: 用于批量导入如下类型的节点
  803. * 234
  804. * 3456346 asadf
  805. * 12312414
  806. * wereww
  807. * 12314
  808. * 1231412
  809. * 13123
  810. */
  811. Text2Children: function(node, text) {
  812. if (!(node instanceof kityminder.Node)) {
  813. return;
  814. }
  815. var children = [], jsonMap = {}, level = 0;
  816. var LINE_SPLITTER = /\r|\n|\r\n/, TAB_REGEXP = /^(\t|\x20{4})/;
  817. var lines = text.split(LINE_SPLITTER), line = "", jsonNode, i = 0;
  818. var minder = this;
  819. function isEmpty(line) {
  820. return line === "" && !/\S/.test(line);
  821. }
  822. function getNode(line) {
  823. return {
  824. data: {
  825. text: line.replace(/^(\t|\x20{4})+/, "").replace(/(\t|\x20{4})+$/, "")
  826. },
  827. children: []
  828. };
  829. }
  830. function getLevel(text) {
  831. var level = 0;
  832. while (TAB_REGEXP.test(text)) {
  833. text = text.replace(TAB_REGEXP, "");
  834. level++;
  835. }
  836. return level;
  837. }
  838. function addChild(parent, node) {
  839. parent.children.push(node);
  840. }
  841. function importChildren(node, children) {
  842. for (var i = 0, l = children.length; i < l; i++) {
  843. var childNode = minder.createNode(null, node);
  844. childNode.setData("text", children[i].data.text || "");
  845. importChildren(childNode, children[i].children);
  846. }
  847. }
  848. while ((line = lines[i++]) !== undefined) {
  849. line = line.replace(/&nbsp;/g, "");
  850. if (isEmpty(line)) continue;
  851. level = getLevel(line);
  852. jsonNode = getNode(line);
  853. if (level === 0) {
  854. jsonMap = {};
  855. children.push(jsonNode);
  856. jsonMap[0] = children[children.length - 1];
  857. } else {
  858. if (!jsonMap[level - 1]) {
  859. throw new Error("Invalid local format");
  860. }
  861. addChild(jsonMap[level - 1], jsonNode);
  862. jsonMap[level] = jsonNode;
  863. }
  864. }
  865. importChildren(node, children);
  866. minder.refresh();
  867. },
  868. /**
  869. * @method exportNode(MinderNode)
  870. * @param {MinderNode} node 当前要被导出的节点
  871. * @return {Object} 返回只含有data和children的Object
  872. * @Editor: Naixor
  873. * @Date: 2015.9.22
  874. */
  875. exportNode: function(node) {
  876. var exported = {};
  877. exported.data = node.getData();
  878. var childNodes = node.getChildren();
  879. exported.children = [];
  880. for (var i = 0; i < childNodes.length; i++) {
  881. exported.children.push(this.exportNode(childNodes[i]));
  882. }
  883. return exported;
  884. },
  885. /**
  886. * @method importNode()
  887. * @description 根据纯json {data, children}数据转换成为脑图节点
  888. * @Editor: Naixor
  889. * @Date: 2015.9.20
  890. */
  891. importNode: function(node, json) {
  892. var data = json.data;
  893. node.data = {};
  894. for (var field in data) {
  895. node.setData(field, data[field]);
  896. }
  897. var childrenTreeData = json.children || [];
  898. for (var i = 0; i < childrenTreeData.length; i++) {
  899. var childNode = this.createNode(null, node);
  900. this.importNode(childNode, childrenTreeData[i]);
  901. }
  902. return node;
  903. },
  904. /**
  905. * @method importJson()
  906. * @for Minder
  907. * @description 导入脑图数据,数据为 JSON 对象,具体的数据字段形式请参考 [Data](data) 章节。
  908. *
  909. * @grammar importJson(json) => {this}
  910. *
  911. * @param {plain} json 要导入的数据
  912. */
  913. importJson: function(json) {
  914. if (!json) return;
  915. /**
  916. * @event preimport
  917. * @for Minder
  918. * @when 导入数据之前
  919. */
  920. this._fire(new MinderEvent("preimport", null, false));
  921. // 删除当前所有节点
  922. while (this._root.getChildren().length) {
  923. this.removeNode(this._root.getChildren()[0]);
  924. }
  925. json = compatibility(json);
  926. this.importNode(this._root, json.root);
  927. this.setTemplate(json.template || "default");
  928. this.setTheme(json.theme || null);
  929. this.refresh();
  930. /**
  931. * @event import,contentchange,interactchange
  932. * @for Minder
  933. * @when 导入数据之后
  934. */
  935. this.fire("import");
  936. this._firePharse({
  937. type: "contentchange"
  938. });
  939. this._interactChange();
  940. return this;
  941. },
  942. /**
  943. * @method exportData()
  944. * @for Minder
  945. * @description 使用指定使用的数据协议,导入脑图数据
  946. *
  947. * @grammar exportData(protocol) => Promise<data>
  948. *
  949. * @param {string} protocol 指定的数据协议(默认内置五种数据协议 `json`、`text`、`markdown`、`svg` 和 `png`)
  950. */
  951. exportData: function(protocolName, option) {
  952. var json, protocol;
  953. json = this.exportJson();
  954. // 指定了协议进行导出,需要检测协议是否支持
  955. if (protocolName) {
  956. protocol = protocols[protocolName];
  957. if (!protocol || !protocol.encode) {
  958. return Promise.reject(new Error("Not supported protocol:" + protocolName));
  959. }
  960. }
  961. // 导出前抛个事件
  962. this._fire(new MinderEvent("beforeexport", {
  963. json: json,
  964. protocolName: protocolName,
  965. protocol: protocol
  966. }));
  967. return Promise.resolve(protocol.encode(json, this, option));
  968. },
  969. /**
  970. * @method importData()
  971. * @for Minder
  972. * @description 使用指定的数据协议,导入脑图数据,覆盖当前实例的脑图
  973. *
  974. * @grammar importData(protocol, callback) => Promise<json>
  975. *
  976. * @param {string} protocol 指定的用于解析数据的数据协议(默认内置三种数据协议 `json`、`text` 和 `markdown` 的支持)
  977. * @param {any} data 要导入的数据
  978. */
  979. importData: function(protocolName, data, option) {
  980. var json, protocol;
  981. var minder = this;
  982. // 指定了协议进行导入,需要检测协议是否支持
  983. if (protocolName) {
  984. protocol = protocols[protocolName];
  985. if (!protocol || !protocol.decode) {
  986. return Promise.reject(new Error("Not supported protocol:" + protocolName));
  987. }
  988. }
  989. var params = {
  990. local: data,
  991. protocolName: protocolName,
  992. protocol: protocol
  993. };
  994. // 导入前抛事件
  995. this._fire(new MinderEvent("beforeimport", params));
  996. return Promise.resolve(protocol.decode(data, this, option)).then(function(json) {
  997. minder.importJson(json);
  998. return json;
  999. });
  1000. },
  1001. /**
  1002. * @method decodeData()
  1003. * @for Minder
  1004. * @description 使用指定的数据协议,解析为脑图数据,与 importData 的区别在于:不覆盖当前实例的脑图
  1005. *
  1006. * @grammar decodeData(protocol, callback) => Promise<json>
  1007. *
  1008. * @param {string} protocol 指定的用于解析数据的数据协议(默认内置三种数据协议 `json`、`text` 和 `markdown` 的支持)
  1009. * @param {any} data 要导入的数据
  1010. */
  1011. decodeData: function(protocolName, data, option) {
  1012. var json, protocol;
  1013. var minder = this;
  1014. // 指定了协议进行导入,需要检测协议是否支持
  1015. if (protocolName) {
  1016. protocol = protocols[protocolName];
  1017. if (!protocol || !protocol.decode) {
  1018. return Promise.reject(new Error("Not supported protocol:" + protocolName));
  1019. }
  1020. }
  1021. var params = {
  1022. local: data,
  1023. protocolName: protocolName,
  1024. protocol: protocol
  1025. };
  1026. // 导入前抛事件
  1027. this._fire(new MinderEvent("beforeimport", params));
  1028. return Promise.resolve(protocol.decode(data, this, option));
  1029. }
  1030. });
  1031. }
  1032. };
  1033. //src/core/event.js
  1034. _p[13] = {
  1035. value: function(require, exports, module) {
  1036. var kity = _p.r(17);
  1037. var utils = _p.r(33);
  1038. var Minder = _p.r(19);
  1039. /**
  1040. * @class MinderEvent
  1041. * @description 表示一个脑图中发生的事件
  1042. */
  1043. var MinderEvent = kity.createClass("MindEvent", {
  1044. constructor: function(type, params, canstop) {
  1045. params = params || {};
  1046. if (params.getType && params.getType() == "ShapeEvent") {
  1047. /**
  1048. * @property kityEvent
  1049. * @for MinderEvent
  1050. * @description 如果事件是从一个 kity 的事件派生的,会有 kityEvent 属性指向原来的 kity 事件
  1051. * @type {KityEvent}
  1052. */
  1053. this.kityEvent = params;
  1054. /**
  1055. * @property originEvent
  1056. * @for MinderEvent
  1057. * @description 如果事件是从原声 Dom 事件派生的(如 click、mousemove 等),会有 originEvent 指向原来的 Dom 事件
  1058. * @type {DomEvent}
  1059. */
  1060. this.originEvent = params.originEvent;
  1061. } else if (params.target && params.preventDefault) {
  1062. this.originEvent = params;
  1063. } else {
  1064. kity.Utils.extend(this, params);
  1065. }
  1066. /**
  1067. * @property type
  1068. * @for MinderEvent
  1069. * @description 事件的类型,如 `click`、`contentchange` 等
  1070. * @type {string}
  1071. */
  1072. this.type = type;
  1073. this._canstop = canstop || false;
  1074. },
  1075. /**
  1076. * @method getPosition()
  1077. * @for MinderEvent
  1078. * @description 如果事件是从一个 kity 事件派生的,会有 `getPosition()` 获取事件发生的坐标
  1079. *
  1080. * @grammar getPosition(refer) => {kity.Point}
  1081. *
  1082. * @param {string|kity.Shape} refer
  1083. * 参照的坐标系,
  1084. * `"screen"` - 以浏览器屏幕为参照坐标系
  1085. * `"minder"` - (默认)以脑图画布为参照坐标系
  1086. * `{kity.Shape}` - 指定以某个 kity 图形为参照坐标系
  1087. */
  1088. getPosition: function(refer) {
  1089. if (!this.kityEvent) return;
  1090. if (!refer || refer == "minder") {
  1091. return this.kityEvent.getPosition(this.minder.getRenderContainer());
  1092. }
  1093. return this.kityEvent.getPosition.call(this.kityEvent, refer);
  1094. },
  1095. /**
  1096. * @method getTargetNode()
  1097. * @for MinderEvent
  1098. * @description 当发生的事件是鼠标事件时,获取事件位置命中的脑图节点
  1099. *
  1100. * @grammar getTargetNode() => {MinderNode}
  1101. */
  1102. getTargetNode: function() {
  1103. var findShape = this.kityEvent && this.kityEvent.targetShape;
  1104. if (!findShape) return null;
  1105. while (!findShape.minderNode && findShape.container) {
  1106. findShape = findShape.container;
  1107. }
  1108. var node = findShape.minderNode;
  1109. if (node && findShape.getOpacity() < 1) return null;
  1110. return node || null;
  1111. },
  1112. /**
  1113. * @method stopPropagation()
  1114. * @for MinderEvent
  1115. * @description 当发生的事件是鼠标事件时,获取事件位置命中的脑图节点
  1116. *
  1117. * @grammar getTargetNode() => {MinderNode}
  1118. */
  1119. stopPropagation: function() {
  1120. this._stoped = true;
  1121. },
  1122. stopPropagationImmediately: function() {
  1123. this._immediatelyStoped = true;
  1124. this._stoped = true;
  1125. },
  1126. shouldStopPropagation: function() {
  1127. return this._canstop && this._stoped;
  1128. },
  1129. shouldStopPropagationImmediately: function() {
  1130. return this._canstop && this._immediatelyStoped;
  1131. },
  1132. preventDefault: function() {
  1133. this.originEvent.preventDefault();
  1134. },
  1135. isRightMB: function() {
  1136. var isRightMB = false;
  1137. if (!this.originEvent) {
  1138. return false;
  1139. }
  1140. if ("which" in this.originEvent) isRightMB = this.originEvent.which == 3; else if ("button" in this.originEvent) isRightMB = this.originEvent.button == 2;
  1141. return isRightMB;
  1142. },
  1143. getKeyCode: function() {
  1144. var evt = this.originEvent;
  1145. return evt.keyCode || evt.which;
  1146. }
  1147. });
  1148. Minder.registerInitHook(function(option) {
  1149. this._initEvents();
  1150. });
  1151. kity.extendClass(Minder, {
  1152. _initEvents: function() {
  1153. this._eventCallbacks = {};
  1154. },
  1155. _resetEvents: function() {
  1156. this._initEvents();
  1157. this._bindEvents();
  1158. },
  1159. _bindEvents: function() {
  1160. /* jscs:disable maximumLineLength */
  1161. this._paper.on("click dblclick mousedown contextmenu mouseup mousemove mouseover mousewheel DOMMouseScroll touchstart touchmove touchend dragenter dragleave drop", this._firePharse.bind(this));
  1162. if (window) {
  1163. window.addEventListener("resize", this._firePharse.bind(this));
  1164. }
  1165. },
  1166. /**
  1167. * @method dispatchKeyEvent
  1168. * @description 派发键盘(相关)事件到脑图实例上,让实例的模块处理
  1169. * @grammar dispatchKeyEvent(e) => {this}
  1170. * @param {Event} e 原生的 Dom 事件对象
  1171. */
  1172. dispatchKeyEvent: function(e) {
  1173. this._firePharse(e);
  1174. },
  1175. _firePharse: function(e) {
  1176. var beforeEvent, preEvent, executeEvent;
  1177. if (e.type == "DOMMouseScroll") {
  1178. e.type = "mousewheel";
  1179. e.wheelDelta = e.originEvent.wheelDelta = e.originEvent.detail * -10;
  1180. e.wheelDeltaX = e.originEvent.mozMovementX;
  1181. e.wheelDeltaY = e.originEvent.mozMovementY;
  1182. }
  1183. beforeEvent = new MinderEvent("before" + e.type, e, true);
  1184. if (this._fire(beforeEvent)) {
  1185. return;
  1186. }
  1187. preEvent = new MinderEvent("pre" + e.type, e, true);
  1188. executeEvent = new MinderEvent(e.type, e, true);
  1189. if (this._fire(preEvent) || this._fire(executeEvent)) this._fire(new MinderEvent("after" + e.type, e, false));
  1190. },
  1191. _interactChange: function(e) {
  1192. var me = this;
  1193. if (me._interactScheduled) return;
  1194. setTimeout(function() {
  1195. me._fire(new MinderEvent("interactchange"));
  1196. me._interactScheduled = false;
  1197. }, 100);
  1198. me._interactScheduled = true;
  1199. },
  1200. _listen: function(type, callback) {
  1201. var callbacks = this._eventCallbacks[type] || (this._eventCallbacks[type] = []);
  1202. callbacks.push(callback);
  1203. },
  1204. _fire: function(e) {
  1205. /**
  1206. * @property minder
  1207. * @description 产生事件的 Minder 对象
  1208. * @for MinderShape
  1209. * @type {Minder}
  1210. */
  1211. e.minder = this;
  1212. var status = this.getStatus();
  1213. var callbacks = this._eventCallbacks[e.type.toLowerCase()] || [];
  1214. if (status) {
  1215. callbacks = callbacks.concat(this._eventCallbacks[status + "." + e.type.toLowerCase()] || []);
  1216. }
  1217. if (callbacks.length === 0) {
  1218. return;
  1219. }
  1220. var lastStatus = this.getStatus();
  1221. for (var i = 0; i < callbacks.length; i++) {
  1222. callbacks[i].call(this, e);
  1223. /* this.getStatus() != lastStatus ||*/
  1224. if (e.shouldStopPropagationImmediately()) {
  1225. break;
  1226. }
  1227. }
  1228. return e.shouldStopPropagation();
  1229. },
  1230. on: function(name, callback) {
  1231. var km = this;
  1232. name.split(/\s+/).forEach(function(n) {
  1233. km._listen(n.toLowerCase(), callback);
  1234. });
  1235. return this;
  1236. },
  1237. off: function(name, callback) {
  1238. var types = name.split(/\s+/);
  1239. var i, j, callbacks, removeIndex;
  1240. for (i = 0; i < types.length; i++) {
  1241. callbacks = this._eventCallbacks[types[i].toLowerCase()];
  1242. if (callbacks) {
  1243. removeIndex = null;
  1244. for (j = 0; j < callbacks.length; j++) {
  1245. if (callbacks[j] == callback) {
  1246. removeIndex = j;
  1247. }
  1248. }
  1249. if (removeIndex !== null) {
  1250. callbacks.splice(removeIndex, 1);
  1251. }
  1252. }
  1253. }
  1254. },
  1255. fire: function(type, params) {
  1256. var e = new MinderEvent(type, params);
  1257. this._fire(e);
  1258. return this;
  1259. }
  1260. });
  1261. module.exports = MinderEvent;
  1262. }
  1263. };
  1264. //src/core/focus.js
  1265. _p[14] = {
  1266. value: function(require, exports, module) {
  1267. var kity = _p.r(17);
  1268. var Minder = _p.r(19);
  1269. Minder.registerInitHook(function() {
  1270. this.on("beforemousedown", function(e) {
  1271. this.focus();
  1272. e.preventDefault();
  1273. });
  1274. this.on("paperrender", function() {
  1275. this.focus();
  1276. });
  1277. });
  1278. kity.extendClass(Minder, {
  1279. focus: function() {
  1280. if (!this.isFocused()) {
  1281. var renderTarget = this._renderTarget;
  1282. renderTarget.classList.add("focus");
  1283. this.renderNodeBatch(this.getSelectedNodes());
  1284. }
  1285. this.fire("focus");
  1286. return this;
  1287. },
  1288. blur: function() {
  1289. if (this.isFocused()) {
  1290. var renderTarget = this._renderTarget;
  1291. renderTarget.classList.remove("focus");
  1292. this.renderNodeBatch(this.getSelectedNodes());
  1293. }
  1294. this.fire("blur");
  1295. return this;
  1296. },
  1297. isFocused: function() {
  1298. var renderTarget = this._renderTarget;
  1299. return renderTarget && renderTarget.classList.contains("focus");
  1300. }
  1301. });
  1302. }
  1303. };
  1304. //src/core/keymap.js
  1305. _p[15] = {
  1306. value: function(require, exports, module) {
  1307. var keymap = {
  1308. Backspace: 8,
  1309. Tab: 9,
  1310. Enter: 13,
  1311. Shift: 16,
  1312. Control: 17,
  1313. Alt: 18,
  1314. CapsLock: 20,
  1315. Esc: 27,
  1316. Spacebar: 32,
  1317. PageUp: 33,
  1318. PageDown: 34,
  1319. End: 35,
  1320. Home: 36,
  1321. Insert: 45,
  1322. Left: 37,
  1323. Up: 38,
  1324. Right: 39,
  1325. Down: 40,
  1326. direction: {
  1327. 37: 1,
  1328. 38: 1,
  1329. 39: 1,
  1330. 40: 1
  1331. },
  1332. Del: 46,
  1333. NumLock: 144,
  1334. Cmd: 91,
  1335. CmdFF: 224,
  1336. F1: 112,
  1337. F2: 113,
  1338. F3: 114,
  1339. F4: 115,
  1340. F5: 116,
  1341. F6: 117,
  1342. F7: 118,
  1343. F8: 119,
  1344. F9: 120,
  1345. F10: 121,
  1346. F11: 122,
  1347. F12: 123,
  1348. "`": 192,
  1349. "=": 187,
  1350. "-": 189,
  1351. "/": 191,
  1352. ".": 190,
  1353. controlKeys: {
  1354. 16: 1,
  1355. 17: 1,
  1356. 18: 1,
  1357. 20: 1,
  1358. 91: 1,
  1359. 224: 1
  1360. },
  1361. notContentChange: {
  1362. 13: 1,
  1363. 9: 1,
  1364. 33: 1,
  1365. 34: 1,
  1366. 35: 1,
  1367. 36: 1,
  1368. 16: 1,
  1369. 17: 1,
  1370. 18: 1,
  1371. 20: 1,
  1372. 91: 1,
  1373. //上下左右
  1374. 37: 1,
  1375. 38: 1,
  1376. 39: 1,
  1377. 40: 1,
  1378. 113: 1,
  1379. 114: 1,
  1380. 115: 1,
  1381. 144: 1,
  1382. 27: 1
  1383. },
  1384. isSelectedNodeKey: {
  1385. //上下左右
  1386. 37: 1,
  1387. 38: 1,
  1388. 39: 1,
  1389. 40: 1,
  1390. 13: 1,
  1391. 9: 1
  1392. }
  1393. };
  1394. // 小写适配
  1395. for (var key in keymap) {
  1396. if (keymap.hasOwnProperty(key)) {
  1397. keymap[key.toLowerCase()] = keymap[key];
  1398. }
  1399. }
  1400. var aKeyCode = 65;
  1401. var aCharCode = "a".charCodeAt(0);
  1402. // letters
  1403. "abcdefghijklmnopqrstuvwxyz".split("").forEach(function(letter) {
  1404. keymap[letter] = aKeyCode + (letter.charCodeAt(0) - aCharCode);
  1405. });
  1406. // numbers
  1407. var n = 9;
  1408. do {
  1409. keymap[n.toString()] = n + 48;
  1410. } while (--n);
  1411. module.exports = keymap;
  1412. }
  1413. };
  1414. //src/core/keyreceiver.js
  1415. _p[16] = {
  1416. value: function(require, exports, module) {
  1417. var kity = _p.r(17);
  1418. var utils = _p.r(33);
  1419. var Minder = _p.r(19);
  1420. function listen(element, type, handler) {
  1421. type.split(" ").forEach(function(name) {
  1422. element.addEventListener(name, handler, false);
  1423. });
  1424. }
  1425. Minder.registerInitHook(function(option) {
  1426. this.setDefaultOptions({
  1427. enableKeyReceiver: true
  1428. });
  1429. if (this.getOption("enableKeyReceiver")) {
  1430. this.on("paperrender", function() {
  1431. this._initKeyReceiver();
  1432. });
  1433. }
  1434. });
  1435. kity.extendClass(Minder, {
  1436. _initKeyReceiver: function() {
  1437. if (this._keyReceiver) return;
  1438. var receiver = this._keyReceiver = document.createElement("input");
  1439. receiver.classList.add("km-receiver");
  1440. var renderTarget = this._renderTarget;
  1441. renderTarget.appendChild(receiver);
  1442. var minder = this;
  1443. listen(receiver, "keydown keyup keypress copy paste blur focus input", function(e) {
  1444. switch (e.type) {
  1445. case "blur":
  1446. minder.blur();
  1447. break;
  1448. case "focus":
  1449. minder.focus();
  1450. break;
  1451. case "input":
  1452. receiver.value = null;
  1453. break;
  1454. }
  1455. minder._firePharse(e);
  1456. e.preventDefault();
  1457. });
  1458. this.on("focus", function() {
  1459. receiver.select();
  1460. receiver.focus();
  1461. });
  1462. this.on("blur", function() {
  1463. receiver.blur();
  1464. });
  1465. if (this.isFocused()) {
  1466. receiver.select();
  1467. receiver.focus();
  1468. }
  1469. }
  1470. });
  1471. }
  1472. };
  1473. //src/core/kity.js
  1474. /**
  1475. * @fileOverview
  1476. *
  1477. * Kity 引入
  1478. *
  1479. * @author: techird
  1480. * @copyright: Baidu FEX, 2014
  1481. */
  1482. _p[17] = {
  1483. value: function(require, exports, module) {
  1484. module.exports = window.kity;
  1485. }
  1486. };
  1487. //src/core/layout.js
  1488. _p[18] = {
  1489. value: function(require, exports, module) {
  1490. var kity = _p.r(17);
  1491. var utils = _p.r(33);
  1492. var Minder = _p.r(19);
  1493. var MinderNode = _p.r(21);
  1494. var MinderEvent = _p.r(13);
  1495. var Command = _p.r(9);
  1496. var _layouts = {};
  1497. var _defaultLayout;
  1498. function register(name, layout) {
  1499. _layouts[name] = layout;
  1500. _defaultLayout = _defaultLayout || name;
  1501. }
  1502. /**
  1503. * @class Layout 布局基类,具体布局需要从该类派生
  1504. */
  1505. var Layout = kity.createClass("Layout", {
  1506. /**
  1507. * @abstract
  1508. *
  1509. * 子类需要实现的布局算法,该算法输入一个节点,排布该节点的子节点(相对父节点的变换)
  1510. *
  1511. * @param {MinderNode} node 需要布局的节点
  1512. *
  1513. * @example
  1514. *
  1515. * doLayout: function(node) {
  1516. * var children = node.getChildren();
  1517. * // layout calculation
  1518. * children[i].setLayoutTransform(new kity.Matrix().translate(x, y));
  1519. * }
  1520. */
  1521. doLayout: function(parent, children) {
  1522. throw new Error("Not Implement: Layout.doLayout()");
  1523. },
  1524. /**
  1525. * 对齐指定的节点
  1526. *
  1527. * @param {Array<MinderNode>} nodes 要对齐的节点
  1528. * @param {string} border 对齐边界,允许取值 left, right, top, bottom
  1529. *
  1530. */
  1531. align: function(nodes, border, offset) {
  1532. var me = this;
  1533. offset = offset || 0;
  1534. nodes.forEach(function(node) {
  1535. var tbox = me.getTreeBox([ node ]);
  1536. var matrix = node.getLayoutTransform();
  1537. switch (border) {
  1538. case "left":
  1539. return matrix.translate(offset - tbox.left, 0);
  1540. case "right":
  1541. return matrix.translate(offset - tbox.right, 0);
  1542. case "top":
  1543. return matrix.translate(0, offset - tbox.top);
  1544. case "bottom":
  1545. return matrix.translate(0, offset - tbox.bottom);
  1546. }
  1547. });
  1548. },
  1549. stack: function(nodes, axis, distance) {
  1550. var me = this;
  1551. var position = 0;
  1552. distance = distance || function(node, next, axis) {
  1553. return node.getStyle({
  1554. x: "margin-right",
  1555. y: "margin-bottom"
  1556. }[axis]) + next.getStyle({
  1557. x: "margin-left",
  1558. y: "margin-top"
  1559. }[axis]);
  1560. };
  1561. nodes.forEach(function(node, index, nodes) {
  1562. var tbox = me.getTreeBox([ node ]);
  1563. var size = {
  1564. x: tbox.width,
  1565. y: tbox.height
  1566. }[axis];
  1567. var offset = {
  1568. x: tbox.left,
  1569. y: tbox.top
  1570. }[axis];
  1571. var matrix = node.getLayoutTransform();
  1572. if (axis == "x") {
  1573. matrix.translate(position - offset, 0);
  1574. } else {
  1575. matrix.translate(0, position - offset);
  1576. }
  1577. position += size;
  1578. if (nodes[index + 1]) position += distance(node, nodes[index + 1], axis);
  1579. });
  1580. return position;
  1581. },
  1582. move: function(nodes, dx, dy) {
  1583. nodes.forEach(function(node) {
  1584. node.getLayoutTransform().translate(dx, dy);
  1585. });
  1586. },
  1587. /**
  1588. * 工具方法:获取给点的节点所占的布局区域
  1589. *
  1590. * @param {MinderNode[]} nodes 需要计算的节点
  1591. *
  1592. * @return {Box} 计算结果
  1593. */
  1594. getBranchBox: function(nodes) {
  1595. var box = new kity.Box();
  1596. var i, node, matrix, contentBox;
  1597. for (i = 0; i < nodes.length; i++) {
  1598. node = nodes[i];
  1599. matrix = node.getLayoutTransform();
  1600. contentBox = node.getContentBox();
  1601. box = box.merge(matrix.transformBox(contentBox));
  1602. }
  1603. return box;
  1604. },
  1605. /**
  1606. * 工具方法:计算给定的节点的子树所占的布局区域
  1607. *
  1608. * @param {MinderNode} nodes 需要计算的节点
  1609. *
  1610. * @return {Box} 计算的结果
  1611. */
  1612. getTreeBox: function(nodes) {
  1613. var i, node, matrix, treeBox;
  1614. var box = new kity.Box();
  1615. if (!(nodes instanceof Array)) nodes = [ nodes ];
  1616. for (i = 0; i < nodes.length; i++) {
  1617. node = nodes[i];
  1618. matrix = node.getLayoutTransform();
  1619. treeBox = node.getContentBox();
  1620. if (node.isExpanded() && node.children.length) {
  1621. treeBox = treeBox.merge(this.getTreeBox(node.children));
  1622. }
  1623. box = box.merge(matrix.transformBox(treeBox));
  1624. }
  1625. return box;
  1626. },
  1627. getOrderHint: function(node) {
  1628. return [];
  1629. }
  1630. });
  1631. Layout.register = register;
  1632. Minder.registerInitHook(function(options) {
  1633. this.refresh();
  1634. });
  1635. /**
  1636. * 布局支持池子管理
  1637. */
  1638. utils.extend(Minder, {
  1639. getLayoutList: function() {
  1640. return _layouts;
  1641. },
  1642. getLayoutInstance: function(name) {
  1643. var LayoutClass = _layouts[name];
  1644. if (!LayoutClass) throw new Error("Missing Layout: " + name);
  1645. var layout = new LayoutClass();
  1646. return layout;
  1647. }
  1648. });
  1649. /**
  1650. * MinderNode 上的布局支持
  1651. */
  1652. kity.extendClass(MinderNode, {
  1653. /**
  1654. * 获得当前节点的布局名称
  1655. *
  1656. * @return {String}
  1657. */
  1658. getLayout: function() {
  1659. var layout = this.getData("layout");
  1660. layout = layout || (this.isRoot() ? _defaultLayout : this.parent.getLayout());
  1661. return layout;
  1662. },
  1663. setLayout: function(name) {
  1664. if (name) {
  1665. if (name == "inherit") {
  1666. this.setData("layout");
  1667. } else {
  1668. this.setData("layout", name);
  1669. }
  1670. }
  1671. return this;
  1672. },
  1673. layout: function(name) {
  1674. this.setLayout(name).getMinder().layout();
  1675. return this;
  1676. },
  1677. getLayoutInstance: function() {
  1678. return Minder.getLayoutInstance(this.getLayout());
  1679. },
  1680. getOrderHint: function(refer) {
  1681. return this.parent.getLayoutInstance().getOrderHint(this);
  1682. },
  1683. /**
  1684. * 获取当前节点相对于父节点的布局变换
  1685. */
  1686. getLayoutTransform: function() {
  1687. return this._layoutTransform || new kity.Matrix();
  1688. },
  1689. /**
  1690. * 第一轮布局计算后,获得的全局布局位置
  1691. *
  1692. * @return {[type]} [description]
  1693. */
  1694. getGlobalLayoutTransformPreview: function() {
  1695. var pMatrix = this.parent ? this.parent.getLayoutTransform() : new kity.Matrix();
  1696. var matrix = this.getLayoutTransform();
  1697. var offset = this.getLayoutOffset();
  1698. if (offset) {
  1699. matrix = matrix.clone().translate(offset.x, offset.y);
  1700. }
  1701. return pMatrix.merge(matrix);
  1702. },
  1703. getLayoutPointPreview: function() {
  1704. return this.getGlobalLayoutTransformPreview().transformPoint(new kity.Point());
  1705. },
  1706. /**
  1707. * 获取节点相对于全局的布局变换
  1708. */
  1709. getGlobalLayoutTransform: function() {
  1710. if (this._globalLayoutTransform) {
  1711. return this._globalLayoutTransform;
  1712. } else if (this.parent) {
  1713. return this.parent.getGlobalLayoutTransform();
  1714. } else {
  1715. return new kity.Matrix();
  1716. }
  1717. },
  1718. /**
  1719. * 设置当前节点相对于父节点的布局变换
  1720. */
  1721. setLayoutTransform: function(matrix) {
  1722. this._layoutTransform = matrix;
  1723. return this;
  1724. },
  1725. /**
  1726. * 设置当前节点相对于全局的布局变换(冗余优化)
  1727. */
  1728. setGlobalLayoutTransform: function(matrix) {
  1729. this.getRenderContainer().setMatrix(this._globalLayoutTransform = matrix);
  1730. return this;
  1731. },
  1732. setVertexIn: function(p) {
  1733. this._vertexIn = p;
  1734. },
  1735. setVertexOut: function(p) {
  1736. this._vertexOut = p;
  1737. },
  1738. getVertexIn: function() {
  1739. return this._vertexIn || new kity.Point();
  1740. },
  1741. getVertexOut: function() {
  1742. return this._vertexOut || new kity.Point();
  1743. },
  1744. getLayoutVertexIn: function() {
  1745. return this.getGlobalLayoutTransform().transformPoint(this.getVertexIn());
  1746. },
  1747. getLayoutVertexOut: function() {
  1748. return this.getGlobalLayoutTransform().transformPoint(this.getVertexOut());
  1749. },
  1750. setLayoutVectorIn: function(v) {
  1751. this._layoutVectorIn = v;
  1752. return this;
  1753. },
  1754. setLayoutVectorOut: function(v) {
  1755. this._layoutVectorOut = v;
  1756. return this;
  1757. },
  1758. getLayoutVectorIn: function() {
  1759. return this._layoutVectorIn || new kity.Vector();
  1760. },
  1761. getLayoutVectorOut: function() {
  1762. return this._layoutVectorOut || new kity.Vector();
  1763. },
  1764. getLayoutBox: function() {
  1765. var matrix = this.getGlobalLayoutTransform();
  1766. return matrix.transformBox(this.getContentBox());
  1767. },
  1768. getLayoutPoint: function() {
  1769. var matrix = this.getGlobalLayoutTransform();
  1770. return matrix.transformPoint(new kity.Point());
  1771. },
  1772. getLayoutOffset: function() {
  1773. if (!this.parent) return new kity.Point();
  1774. // 影响当前节点位置的是父节点的布局
  1775. var data = this.getData("layout_" + this.parent.getLayout() + "_offset");
  1776. if (data) return new kity.Point(data.x, data.y);
  1777. return new kity.Point();
  1778. },
  1779. setLayoutOffset: function(p) {
  1780. if (!this.parent) return this;
  1781. this.setData("layout_" + this.parent.getLayout() + "_offset", p ? {
  1782. x: p.x,
  1783. y: p.y
  1784. } : undefined);
  1785. return this;
  1786. },
  1787. hasLayoutOffset: function() {
  1788. return !!this.getData("layout_" + this.parent.getLayout() + "_offset");
  1789. },
  1790. resetLayoutOffset: function() {
  1791. return this.setLayoutOffset(null);
  1792. },
  1793. getLayoutRoot: function() {
  1794. if (this.isLayoutRoot()) {
  1795. return this;
  1796. }
  1797. return this.parent.getLayoutRoot();
  1798. },
  1799. isLayoutRoot: function() {
  1800. return this.getData("layout") || this.isRoot();
  1801. }
  1802. });
  1803. /**
  1804. * Minder 上的布局支持
  1805. */
  1806. kity.extendClass(Minder, {
  1807. layout: function() {
  1808. var duration = this.getOption("layoutAnimationDuration");
  1809. this.getRoot().traverse(function(node) {
  1810. // clear last results
  1811. node.setLayoutTransform(null);
  1812. });
  1813. function layoutNode(node, round) {
  1814. // layout all children first
  1815. // 剪枝:收起的节点无需计算
  1816. if (node.isExpanded() || true) {
  1817. node.children.forEach(function(child) {
  1818. layoutNode(child, round);
  1819. });
  1820. }
  1821. var layout = node.getLayoutInstance();
  1822. // var childrenInFlow = node.getChildren().filter(function(child) {
  1823. // return !child.hasLayoutOffset();
  1824. // });
  1825. layout.doLayout(node, node.getChildren(), round);
  1826. }
  1827. // 第一轮布局
  1828. layoutNode(this.getRoot(), 1);
  1829. // 第二轮布局
  1830. layoutNode(this.getRoot(), 2);
  1831. var minder = this;
  1832. this.applyLayoutResult(this.getRoot(), duration, function() {
  1833. /**
  1834. * 当节点>200, 不使用动画时, 此处逻辑变为同步逻辑, 外部minder.on事件无法
  1835. * 被提前录入, 因此增加setTimeout
  1836. * @author Naixor
  1837. */
  1838. setTimeout(function() {
  1839. minder.fire("layoutallfinish");
  1840. }, 0);
  1841. });
  1842. return this.fire("layout");
  1843. },
  1844. refresh: function() {
  1845. this.getRoot().renderTree();
  1846. this.layout().fire("contentchange")._interactChange();
  1847. return this;
  1848. },
  1849. applyLayoutResult: function(root, duration, callback) {
  1850. root = root || this.getRoot();
  1851. var me = this;
  1852. var complex = root.getComplex();
  1853. function consume() {
  1854. if (!--complex) {
  1855. if (callback) {
  1856. callback();
  1857. }
  1858. }
  1859. }
  1860. // 节点复杂度大于 100,关闭动画
  1861. if (complex > 200) duration = 0;
  1862. function applyMatrix(node, matrix) {
  1863. node.setGlobalLayoutTransform(matrix);
  1864. me.fire("layoutapply", {
  1865. node: node,
  1866. matrix: matrix
  1867. });
  1868. }
  1869. function apply(node, pMatrix) {
  1870. var matrix = node.getLayoutTransform().merge(pMatrix.clone());
  1871. var lastMatrix = node.getGlobalLayoutTransform() || new kity.Matrix();
  1872. var offset = node.getLayoutOffset();
  1873. matrix.translate(offset.x, offset.y);
  1874. matrix.m.e = Math.round(matrix.m.e);
  1875. matrix.m.f = Math.round(matrix.m.f);
  1876. // 如果当前有动画,停止动画
  1877. if (node._layoutTimeline) {
  1878. node._layoutTimeline.stop();
  1879. node._layoutTimeline = null;
  1880. }
  1881. // 如果要求以动画形式来更新,创建动画
  1882. if (duration) {
  1883. node._layoutTimeline = new kity.Animator(lastMatrix, matrix, applyMatrix).start(node, duration, "ease").on("finish", function() {
  1884. //可能性能低的时候会丢帧,手动添加一帧
  1885. setTimeout(function() {
  1886. applyMatrix(node, matrix);
  1887. me.fire("layoutfinish", {
  1888. node: node,
  1889. matrix: matrix
  1890. });
  1891. consume();
  1892. }, 150);
  1893. });
  1894. } else {
  1895. applyMatrix(node, matrix);
  1896. me.fire("layoutfinish", {
  1897. node: node,
  1898. matrix: matrix
  1899. });
  1900. consume();
  1901. }
  1902. for (var i = 0; i < node.children.length; i++) {
  1903. apply(node.children[i], matrix);
  1904. }
  1905. }
  1906. apply(root, root.parent ? root.parent.getGlobalLayoutTransform() : new kity.Matrix());
  1907. return this;
  1908. }
  1909. });
  1910. module.exports = Layout;
  1911. }
  1912. };
  1913. //src/core/minder.js
  1914. /**
  1915. * @fileOverview
  1916. *
  1917. * KityMinder 类,暴露在 window 上的唯一变量
  1918. *
  1919. * @author: techird
  1920. * @copyright: Baidu FEX, 2014
  1921. */
  1922. _p[19] = {
  1923. value: function(require, exports, module) {
  1924. var kity = _p.r(17);
  1925. var utils = _p.r(33);
  1926. var _initHooks = [];
  1927. var Minder = kity.createClass("Minder", {
  1928. constructor: function(options) {
  1929. this._options = utils.extend({}, options);
  1930. var initHooks = _initHooks.slice();
  1931. var initHook;
  1932. while (initHooks.length) {
  1933. initHook = initHooks.shift();
  1934. if (typeof initHook == "function") {
  1935. initHook.call(this, this._options);
  1936. }
  1937. }
  1938. this.fire("finishInitHook");
  1939. }
  1940. });
  1941. Minder.version = "1.4.43";
  1942. Minder.registerInitHook = function(hook) {
  1943. _initHooks.push(hook);
  1944. };
  1945. module.exports = Minder;
  1946. }
  1947. };
  1948. //src/core/module.js
  1949. _p[20] = {
  1950. value: function(require, exports, module) {
  1951. var kity = _p.r(17);
  1952. var utils = _p.r(33);
  1953. var Minder = _p.r(19);
  1954. /* 已注册的模块 */
  1955. var _modules = {};
  1956. exports.register = function(name, module) {
  1957. _modules[name] = module;
  1958. };
  1959. /* 模块初始化 */
  1960. Minder.registerInitHook(function() {
  1961. this._initModules();
  1962. });
  1963. // 模块声明周期维护
  1964. kity.extendClass(Minder, {
  1965. _initModules: function() {
  1966. var modulesPool = _modules;
  1967. var modulesToLoad = this._options.modules || utils.keys(modulesPool);
  1968. this._commands = {};
  1969. this._query = {};
  1970. this._modules = {};
  1971. this._rendererClasses = {};
  1972. var i, name, type, module, moduleDeals, dealCommands, dealEvents, dealRenderers;
  1973. var me = this;
  1974. for (i = 0; i < modulesToLoad.length; i++) {
  1975. name = modulesToLoad[i];
  1976. if (!modulesPool[name]) continue;
  1977. // 执行模块初始化,抛出后续处理对象
  1978. if (typeof modulesPool[name] == "function") {
  1979. moduleDeals = modulesPool[name].call(me);
  1980. } else {
  1981. moduleDeals = modulesPool[name];
  1982. }
  1983. this._modules[name] = moduleDeals;
  1984. if (!moduleDeals) continue;
  1985. if (moduleDeals.defaultOptions) {
  1986. me.setDefaultOptions(moduleDeals.defaultOptions);
  1987. }
  1988. if (moduleDeals.init) {
  1989. moduleDeals.init.call(me, this._options);
  1990. }
  1991. /**
  1992. * @Desc: 判断是否支持原生clipboard事件,如果支持,则对pager添加其监听
  1993. * @Editor: Naixor
  1994. * @Date: 2015.9.20
  1995. */
  1996. /**
  1997. * 由于当前脑图解构问题,clipboard暂时全权交由玩不托管
  1998. * @Editor: Naixor
  1999. * @Date: 2015.9.24
  2000. */
  2001. // if (name === 'ClipboardModule' && this.supportClipboardEvent && !kity.Browser.gecko) {
  2002. // var on = function () {
  2003. // var clipBoardReceiver = this.clipBoardReceiver || document;
  2004. // if (document.addEventListener) {
  2005. // clipBoardReceiver.addEventListener.apply(this, arguments);
  2006. // } else {
  2007. // arguments[0] = 'on' + arguments[0];
  2008. // clipBoardReceiver.attachEvent.apply(this, arguments);
  2009. // }
  2010. // }
  2011. // for (var command in moduleDeals.clipBoardEvents) {
  2012. // on(command, moduleDeals.clipBoardEvents[command]);
  2013. // }
  2014. // };
  2015. // command加入命令池子
  2016. dealCommands = moduleDeals.commands;
  2017. for (name in dealCommands) {
  2018. this._commands[name.toLowerCase()] = new dealCommands[name]();
  2019. }
  2020. // 绑定事件
  2021. dealEvents = moduleDeals.events;
  2022. if (dealEvents) {
  2023. for (type in dealEvents) {
  2024. me.on(type, dealEvents[type]);
  2025. }
  2026. }
  2027. // 渲染器
  2028. dealRenderers = moduleDeals.renderers;
  2029. if (dealRenderers) {
  2030. for (type in dealRenderers) {
  2031. this._rendererClasses[type] = this._rendererClasses[type] || [];
  2032. if (utils.isArray(dealRenderers[type])) {
  2033. this._rendererClasses[type] = this._rendererClasses[type].concat(dealRenderers[type]);
  2034. } else {
  2035. this._rendererClasses[type].push(dealRenderers[type]);
  2036. }
  2037. }
  2038. }
  2039. //添加模块的快捷键
  2040. if (moduleDeals.commandShortcutKeys) {
  2041. this.addCommandShortcutKeys(moduleDeals.commandShortcutKeys);
  2042. }
  2043. }
  2044. },
  2045. _garbage: function() {
  2046. this.clearSelect();
  2047. while (this._root.getChildren().length) {
  2048. this._root.removeChild(0);
  2049. }
  2050. },
  2051. destroy: function() {
  2052. var modules = this._modules;
  2053. this._resetEvents();
  2054. this._garbage();
  2055. for (var key in modules) {
  2056. if (!modules[key].destroy) continue;
  2057. modules[key].destroy.call(this);
  2058. }
  2059. },
  2060. reset: function() {
  2061. var modules = this._modules;
  2062. this._garbage();
  2063. for (var key in modules) {
  2064. if (!modules[key].reset) continue;
  2065. modules[key].reset.call(this);
  2066. }
  2067. }
  2068. });
  2069. }
  2070. };
  2071. //src/core/node.js
  2072. _p[21] = {
  2073. value: function(require, exports, module) {
  2074. var kity = _p.r(17);
  2075. var utils = _p.r(33);
  2076. var Minder = _p.r(19);
  2077. /**
  2078. * @class MinderNode
  2079. *
  2080. * 表示一个脑图节点
  2081. */
  2082. var MinderNode = kity.createClass("MinderNode", {
  2083. /**
  2084. * 创建一个游离的脑图节点
  2085. *
  2086. * @param {String|Object} textOrData
  2087. * 节点的初始数据或文本
  2088. */
  2089. constructor: function(textOrData) {
  2090. // 指针
  2091. this.parent = null;
  2092. this.root = this;
  2093. this.children = [];
  2094. // 数据
  2095. this.data = {
  2096. id: utils.guid(),
  2097. created: +new Date()
  2098. };
  2099. // 绘图容器
  2100. this.initContainers();
  2101. if (utils.isString(textOrData)) {
  2102. this.setText(textOrData);
  2103. } else if (utils.isObject(textOrData)) {
  2104. utils.extend(this.data, textOrData);
  2105. }
  2106. },
  2107. initContainers: function() {
  2108. this.rc = new kity.Group().setId(utils.uuid("minder_node"));
  2109. this.rc.minderNode = this;
  2110. },
  2111. /**
  2112. * 判断节点是否根节点
  2113. */
  2114. isRoot: function() {
  2115. return this.root === this;
  2116. },
  2117. /**
  2118. * 判断节点是否叶子
  2119. */
  2120. isLeaf: function() {
  2121. return this.children.length === 0;
  2122. },
  2123. /**
  2124. * 获取节点的根节点
  2125. */
  2126. getRoot: function() {
  2127. return this.root || this;
  2128. },
  2129. /**
  2130. * 获得节点的父节点
  2131. */
  2132. getParent: function() {
  2133. return this.parent;
  2134. },
  2135. getSiblings: function() {
  2136. var children = this.parent.children;
  2137. var siblings = [];
  2138. var self = this;
  2139. children.forEach(function(child) {
  2140. if (child != self) siblings.push(child);
  2141. });
  2142. return siblings;
  2143. },
  2144. /**
  2145. * 获得节点的深度
  2146. */
  2147. getLevel: function() {
  2148. var level = 0, ancestor = this.parent;
  2149. while (ancestor) {
  2150. level++;
  2151. ancestor = ancestor.parent;
  2152. }
  2153. return level;
  2154. },
  2155. /**
  2156. * 获得节点的复杂度(即子树中节点的数量)
  2157. */
  2158. getComplex: function() {
  2159. var complex = 0;
  2160. this.traverse(function() {
  2161. complex++;
  2162. });
  2163. return complex;
  2164. },
  2165. /**
  2166. * 获得节点的类型(root|main|sub)
  2167. */
  2168. getType: function(type) {
  2169. this.type = [ "root", "main", "sub" ][Math.min(this.getLevel(), 2)];
  2170. return this.type;
  2171. },
  2172. /**
  2173. * 判断当前节点是否被测试节点的祖先
  2174. * @param {MinderNode} test 被测试的节点
  2175. */
  2176. isAncestorOf: function(test) {
  2177. var ancestor = test.parent;
  2178. while (ancestor) {
  2179. if (ancestor == this) return true;
  2180. ancestor = ancestor.parent;
  2181. }
  2182. return false;
  2183. },
  2184. getData: function(key) {
  2185. return key ? this.data[key] : this.data;
  2186. },
  2187. setData: function(key, value) {
  2188. if (typeof key == "object") {
  2189. var data = key;
  2190. for (key in data) if (data.hasOwnProperty(key)) {
  2191. this.data[key] = data[key];
  2192. }
  2193. } else {
  2194. this.data[key] = value;
  2195. }
  2196. return this;
  2197. },
  2198. /**
  2199. * 设置节点的文本数据
  2200. * @param {String} text 文本数据
  2201. */
  2202. setText: function(text) {
  2203. return this.data.text = text;
  2204. },
  2205. /**
  2206. * 获取节点的文本数据
  2207. * @return {String}
  2208. */
  2209. getText: function() {
  2210. return this.data.text || null;
  2211. },
  2212. /**
  2213. * 先序遍历当前节点树
  2214. * @param {Function} fn 遍历函数
  2215. */
  2216. preTraverse: function(fn, excludeThis) {
  2217. var children = this.getChildren();
  2218. if (!excludeThis) fn(this);
  2219. for (var i = 0; i < children.length; i++) {
  2220. children[i].preTraverse(fn);
  2221. }
  2222. },
  2223. /**
  2224. * 后序遍历当前节点树
  2225. * @param {Function} fn 遍历函数
  2226. */
  2227. postTraverse: function(fn, excludeThis) {
  2228. var children = this.getChildren();
  2229. for (var i = 0; i < children.length; i++) {
  2230. children[i].postTraverse(fn);
  2231. }
  2232. if (!excludeThis) fn(this);
  2233. },
  2234. traverse: function(fn, excludeThis) {
  2235. return this.postTraverse(fn, excludeThis);
  2236. },
  2237. getChildren: function() {
  2238. return this.children;
  2239. },
  2240. getIndex: function() {
  2241. return this.parent ? this.parent.children.indexOf(this) : -1;
  2242. },
  2243. insertChild: function(node, index) {
  2244. if (index === undefined) {
  2245. index = this.children.length;
  2246. }
  2247. if (node.parent) {
  2248. node.parent.removeChild(node);
  2249. }
  2250. node.parent = this;
  2251. node.root = this.root;
  2252. this.children.splice(index, 0, node);
  2253. },
  2254. appendChild: function(node) {
  2255. return this.insertChild(node);
  2256. },
  2257. prependChild: function(node) {
  2258. return this.insertChild(node, 0);
  2259. },
  2260. removeChild: function(elem) {
  2261. var index = elem, removed;
  2262. if (elem instanceof MinderNode) {
  2263. index = this.children.indexOf(elem);
  2264. }
  2265. if (index >= 0) {
  2266. removed = this.children.splice(index, 1)[0];
  2267. removed.parent = null;
  2268. removed.root = removed;
  2269. }
  2270. },
  2271. clearChildren: function() {
  2272. this.children = [];
  2273. },
  2274. getChild: function(index) {
  2275. return this.children[index];
  2276. },
  2277. getRenderContainer: function() {
  2278. return this.rc;
  2279. },
  2280. getCommonAncestor: function(node) {
  2281. return MinderNode.getCommonAncestor(this, node);
  2282. },
  2283. contains: function(node) {
  2284. return this == node || this.isAncestorOf(node);
  2285. },
  2286. clone: function() {
  2287. var cloned = new MinderNode();
  2288. cloned.data = utils.clone(this.data);
  2289. this.children.forEach(function(child) {
  2290. cloned.appendChild(child.clone());
  2291. });
  2292. return cloned;
  2293. },
  2294. compareTo: function(node) {
  2295. if (!utils.comparePlainObject(this.data, node.data)) return false;
  2296. if (!utils.comparePlainObject(this.temp, node.temp)) return false;
  2297. if (this.children.length != node.children.length) return false;
  2298. var i = 0;
  2299. while (this.children[i]) {
  2300. if (!this.children[i].compareTo(node.children[i])) return false;
  2301. i++;
  2302. }
  2303. return true;
  2304. },
  2305. getMinder: function() {
  2306. return this.getRoot().minder;
  2307. }
  2308. });
  2309. MinderNode.getCommonAncestor = function(nodeA, nodeB) {
  2310. if (nodeA instanceof Array) {
  2311. return MinderNode.getCommonAncestor.apply(this, nodeA);
  2312. }
  2313. switch (arguments.length) {
  2314. case 1:
  2315. return nodeA.parent || nodeA;
  2316. case 2:
  2317. if (nodeA.isAncestorOf(nodeB)) {
  2318. return nodeA;
  2319. }
  2320. if (nodeB.isAncestorOf(nodeA)) {
  2321. return nodeB;
  2322. }
  2323. var ancestor = nodeA.parent;
  2324. while (ancestor && !ancestor.isAncestorOf(nodeB)) {
  2325. ancestor = ancestor.parent;
  2326. }
  2327. return ancestor;
  2328. default:
  2329. return Array.prototype.reduce.call(arguments, function(prev, current) {
  2330. return MinderNode.getCommonAncestor(prev, current);
  2331. }, nodeA);
  2332. }
  2333. };
  2334. kity.extendClass(Minder, {
  2335. getRoot: function() {
  2336. return this._root;
  2337. },
  2338. setRoot: function(root) {
  2339. this._root = root;
  2340. root.minder = this;
  2341. },
  2342. getAllNode: function() {
  2343. var nodes = [];
  2344. this.getRoot().traverse(function(node) {
  2345. nodes.push(node);
  2346. });
  2347. return nodes;
  2348. },
  2349. getNodeById: function(id) {
  2350. return this.getNodesById([ id ])[0];
  2351. },
  2352. getNodesById: function(ids) {
  2353. var nodes = this.getAllNode();
  2354. var result = [];
  2355. nodes.forEach(function(node) {
  2356. if (ids.indexOf(node.getData("id")) != -1) {
  2357. result.push(node);
  2358. }
  2359. });
  2360. return result;
  2361. },
  2362. createNode: function(textOrData, parent, index) {
  2363. var node = new MinderNode(textOrData);
  2364. this.fire("nodecreate", {
  2365. node: node,
  2366. parent: parent,
  2367. index: index
  2368. });
  2369. this.appendNode(node, parent, index);
  2370. return node;
  2371. },
  2372. appendNode: function(node, parent, index) {
  2373. if (parent) parent.insertChild(node, index);
  2374. this.attachNode(node);
  2375. return this;
  2376. },
  2377. removeNode: function(node) {
  2378. if (node.parent) {
  2379. node.parent.removeChild(node);
  2380. this.detachNode(node);
  2381. this.fire("noderemove", {
  2382. node: node
  2383. });
  2384. }
  2385. },
  2386. attachNode: function(node) {
  2387. var rc = this.getRenderContainer();
  2388. node.traverse(function(current) {
  2389. current.attached = true;
  2390. rc.addShape(current.getRenderContainer());
  2391. });
  2392. rc.addShape(node.getRenderContainer());
  2393. this.fire("nodeattach", {
  2394. node: node
  2395. });
  2396. },
  2397. detachNode: function(node) {
  2398. var rc = this.getRenderContainer();
  2399. node.traverse(function(current) {
  2400. current.attached = false;
  2401. rc.removeShape(current.getRenderContainer());
  2402. });
  2403. this.fire("nodedetach", {
  2404. node: node
  2405. });
  2406. },
  2407. getMinderTitle: function() {
  2408. return this.getRoot().getText();
  2409. }
  2410. });
  2411. module.exports = MinderNode;
  2412. }
  2413. };
  2414. //src/core/option.js
  2415. /**
  2416. * @fileOverview
  2417. *
  2418. * 提供脑图选项支持
  2419. *
  2420. * @author: techird
  2421. * @copyright: Baidu FEX, 2014
  2422. */
  2423. _p[22] = {
  2424. value: function(require, exports, module) {
  2425. var kity = _p.r(17);
  2426. var utils = _p.r(33);
  2427. var Minder = _p.r(19);
  2428. Minder.registerInitHook(function(options) {
  2429. this._defaultOptions = {};
  2430. });
  2431. kity.extendClass(Minder, {
  2432. setDefaultOptions: function(options) {
  2433. utils.extend(this._defaultOptions, options);
  2434. return this;
  2435. },
  2436. getOption: function(key) {
  2437. if (key) {
  2438. return key in this._options ? this._options[key] : this._defaultOptions[key];
  2439. } else {
  2440. return utils.extend({}, this._defaultOptions, this._options);
  2441. }
  2442. },
  2443. setOption: function(key, value) {
  2444. this._options[key] = value;
  2445. }
  2446. });
  2447. }
  2448. };
  2449. //src/core/paper.js
  2450. /**
  2451. * @fileOverview
  2452. *
  2453. * 初始化渲染容器
  2454. *
  2455. * @author: techird
  2456. * @copyright: Baidu FEX, 2014
  2457. */
  2458. _p[23] = {
  2459. value: function(require, exports, module) {
  2460. var kity = _p.r(17);
  2461. var utils = _p.r(33);
  2462. var Minder = _p.r(19);
  2463. Minder.registerInitHook(function() {
  2464. this._initPaper();
  2465. });
  2466. kity.extendClass(Minder, {
  2467. _initPaper: function() {
  2468. this._paper = new kity.Paper();
  2469. this._paper._minder = this;
  2470. this._paper.getNode().ondragstart = function(e) {
  2471. e.preventDefault();
  2472. };
  2473. this._paper.shapeNode.setAttribute("transform", "translate(0.5, 0.5)");
  2474. this._addRenderContainer();
  2475. this.setRoot(this.createNode());
  2476. if (this._options.renderTo) {
  2477. this.renderTo(this._options.renderTo);
  2478. }
  2479. },
  2480. _addRenderContainer: function() {
  2481. this._rc = new kity.Group().setId(utils.uuid("minder"));
  2482. this._paper.addShape(this._rc);
  2483. },
  2484. renderTo: function(target) {
  2485. if (typeof target == "string") {
  2486. target = document.querySelector(target);
  2487. }
  2488. if (target) {
  2489. if (target.tagName.toLowerCase() == "script") {
  2490. var newTarget = document.createElement("div");
  2491. newTarget.id = target.id;
  2492. newTarget.class = target.class;
  2493. target.parentNode.insertBefore(newTarget, target);
  2494. target.parentNode.removeChild(target);
  2495. target = newTarget;
  2496. }
  2497. target.classList.add("km-view");
  2498. this._paper.renderTo(this._renderTarget = target);
  2499. this._bindEvents();
  2500. this.fire("paperrender");
  2501. }
  2502. return this;
  2503. },
  2504. getRenderContainer: function() {
  2505. return this._rc;
  2506. },
  2507. getPaper: function() {
  2508. return this._paper;
  2509. },
  2510. getRenderTarget: function() {
  2511. return this._renderTarget;
  2512. }
  2513. });
  2514. }
  2515. };
  2516. //src/core/patch.js
  2517. /**
  2518. * @fileOverview
  2519. *
  2520. * 打补丁
  2521. *
  2522. * @author: techird
  2523. * @copyright: Baidu FEX, 2014
  2524. */
  2525. _p[24] = {
  2526. value: function(require, exports, module) {
  2527. var kity = _p.r(17);
  2528. var Minder = _p.r(19);
  2529. function insertNode(minder, info, parent, index) {
  2530. parent = minder.createNode(info.data, parent, index);
  2531. info.children.forEach(function(childInfo, index) {
  2532. insertNode(minder, childInfo, parent, index);
  2533. });
  2534. return parent;
  2535. }
  2536. function applyPatch(minder, patch) {
  2537. // patch.op - 操作,包括 remove, add, replace
  2538. // patch.path - 路径,如 '/root/children/1/data'
  2539. // patch.value - 数据,如 { text: "思路" }
  2540. var path = patch.path.split("/");
  2541. path.shift();
  2542. var changed = path.shift();
  2543. var node;
  2544. if (changed == "root") {
  2545. var dataIndex = path.indexOf("data");
  2546. if (dataIndex > -1) {
  2547. changed = "data";
  2548. var dataPath = path.splice(dataIndex + 1);
  2549. patch.dataPath = dataPath;
  2550. } else {
  2551. changed = "node";
  2552. }
  2553. node = minder.getRoot();
  2554. var segment, index;
  2555. while (segment = path.shift()) {
  2556. if (segment == "children") continue;
  2557. if (typeof index != "undefined") node = node.getChild(index);
  2558. index = +segment;
  2559. }
  2560. patch.index = index;
  2561. patch.node = node;
  2562. }
  2563. var express = patch.express = [ changed, patch.op ].join(".");
  2564. switch (express) {
  2565. case "theme.replace":
  2566. minder.useTheme(patch.value);
  2567. break;
  2568. case "template.replace":
  2569. minder.useTemplate(patch.value);
  2570. break;
  2571. case "node.add":
  2572. insertNode(minder, patch.value, patch.node, patch.index).renderTree();
  2573. minder.layout();
  2574. break;
  2575. case "node.remove":
  2576. minder.removeNode(patch.node.getChild(patch.index));
  2577. minder.layout();
  2578. break;
  2579. case "data.add":
  2580. case "data.replace":
  2581. case "data.remove":
  2582. var data = patch.node.data;
  2583. var field;
  2584. path = patch.dataPath.slice();
  2585. while (data && path.length > 1) {
  2586. field = path.shift();
  2587. if (field in data) {
  2588. data = data[field];
  2589. } else if (patch.op != "remove") {
  2590. data = data[field] = {};
  2591. }
  2592. }
  2593. if (data) {
  2594. field = path.shift();
  2595. data[field] = patch.value;
  2596. }
  2597. if (field == "expandState") {
  2598. node.renderTree();
  2599. } else {
  2600. node.render();
  2601. }
  2602. minder.layout();
  2603. }
  2604. minder.fire("patch", {
  2605. patch: patch
  2606. });
  2607. }
  2608. kity.extendClass(Minder, {
  2609. applyPatches: function(patches) {
  2610. for (var i = 0; i < patches.length; i++) {
  2611. applyPatch(this, patches[i]);
  2612. }
  2613. this.fire("contentchange");
  2614. return this;
  2615. }
  2616. });
  2617. }
  2618. };
  2619. //src/core/promise.js
  2620. _p[25] = {
  2621. value: function(require, exports, module) {
  2622. /*!
  2623. ** Thenable -- Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable
  2624. ** Copyright (c) 2013-2014 Ralf S. Engelschall <http://engelschall.com>
  2625. ** Licensed under The MIT License <http://opensource.org/licenses/MIT>
  2626. ** Source-Code distributed on <http://github.com/rse/thenable>
  2627. */
  2628. /* promise states [Promises/A+ 2.1] */
  2629. var STATE_PENDING = 0;
  2630. /* [Promises/A+ 2.1.1] */
  2631. var STATE_FULFILLED = 1;
  2632. /* [Promises/A+ 2.1.2] */
  2633. var STATE_REJECTED = 2;
  2634. /* [Promises/A+ 2.1.3] */
  2635. /* promise object constructor */
  2636. var Promise = function(executor) {
  2637. /* optionally support non-constructor/plain-function call */
  2638. if (!(this instanceof Promise)) return new Promise(executor);
  2639. /* initialize object */
  2640. this.id = "Thenable/1.0.7";
  2641. this.state = STATE_PENDING;
  2642. /* initial state */
  2643. this.fulfillValue = undefined;
  2644. /* initial value */
  2645. /* [Promises/A+ 1.3, 2.1.2.2] */
  2646. this.rejectReason = undefined;
  2647. /* initial reason */
  2648. /* [Promises/A+ 1.5, 2.1.3.2] */
  2649. this.onFulfilled = [];
  2650. /* initial handlers */
  2651. this.onRejected = [];
  2652. /* initial handlers */
  2653. /* support optional executor function */
  2654. if (typeof executor === "function") executor.call(this, this.fulfill.bind(this), this.reject.bind(this));
  2655. };
  2656. /* Promise API methods */
  2657. Promise.prototype = {
  2658. /* promise resolving methods */
  2659. fulfill: function(value) {
  2660. return deliver(this, STATE_FULFILLED, "fulfillValue", value);
  2661. },
  2662. reject: function(value) {
  2663. return deliver(this, STATE_REJECTED, "rejectReason", value);
  2664. },
  2665. /* 'The then Method' [Promises/A+ 1.1, 1.2, 2.2] */
  2666. then: function(onFulfilled, onRejected) {
  2667. var curr = this;
  2668. var next = new Promise();
  2669. /* [Promises/A+ 2.2.7] */
  2670. curr.onFulfilled.push(resolver(onFulfilled, next, "fulfill"));
  2671. /* [Promises/A+ 2.2.2/2.2.6] */
  2672. curr.onRejected.push(resolver(onRejected, next, "reject"));
  2673. /* [Promises/A+ 2.2.3/2.2.6] */
  2674. execute(curr);
  2675. return next;
  2676. }
  2677. };
  2678. Promise.all = function(arr) {
  2679. return new Promise(function(resolve, reject) {
  2680. var len = arr.length, i = 0, res = 0, results = [];
  2681. if (len === 0) {
  2682. resolve(results);
  2683. }
  2684. while (i < len) {
  2685. arr[i].then(function(result) {
  2686. results.push(result);
  2687. if (++res === len) {
  2688. resolve(results);
  2689. }
  2690. }, function(val) {
  2691. reject(val);
  2692. });
  2693. i++;
  2694. }
  2695. });
  2696. };
  2697. /* deliver an action */
  2698. var deliver = function(curr, state, name, value) {
  2699. if (curr.state === STATE_PENDING) {
  2700. curr.state = state;
  2701. /* [Promises/A+ 2.1.2.1, 2.1.3.1] */
  2702. curr[name] = value;
  2703. /* [Promises/A+ 2.1.2.2, 2.1.3.2] */
  2704. execute(curr);
  2705. }
  2706. return curr;
  2707. };
  2708. /* execute all handlers */
  2709. var execute = function(curr) {
  2710. if (curr.state === STATE_FULFILLED) execute_handlers(curr, "onFulfilled", curr.fulfillValue); else if (curr.state === STATE_REJECTED) execute_handlers(curr, "onRejected", curr.rejectReason);
  2711. };
  2712. /* execute particular set of handlers */
  2713. var execute_handlers = function(curr, name, value) {
  2714. /* global process: true */
  2715. /* global setImmediate: true */
  2716. /* global setTimeout: true */
  2717. /* short-circuit processing */
  2718. if (curr[name].length === 0) return;
  2719. /* iterate over all handlers, exactly once */
  2720. var handlers = curr[name];
  2721. curr[name] = [];
  2722. /* [Promises/A+ 2.2.2.3, 2.2.3.3] */
  2723. var func = function() {
  2724. for (var i = 0; i < handlers.length; i++) handlers[i](value);
  2725. };
  2726. /* execute procedure asynchronously */
  2727. /* [Promises/A+ 2.2.4, 3.1] */
  2728. if (typeof process === "object" && typeof process.nextTick === "function") process.nextTick(func); else if (typeof setImmediate === "function") setImmediate(func); else setTimeout(func, 0);
  2729. };
  2730. /* generate a resolver function */
  2731. var resolver = function(cb, next, method) {
  2732. return function(value) {
  2733. if (typeof cb !== "function") /* [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4] */
  2734. next[method].call(next, value); else {
  2735. var result;
  2736. try {
  2737. if (value instanceof Promise) {
  2738. result = value.then(cb);
  2739. } else result = cb(value);
  2740. } /* [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2] */
  2741. catch (e) {
  2742. next.reject(e);
  2743. /* [Promises/A+ 2.2.7.2] */
  2744. return;
  2745. }
  2746. resolve(next, result);
  2747. }
  2748. };
  2749. };
  2750. /* 'Promise Resolution Procedure' */
  2751. /* [Promises/A+ 2.3] */
  2752. var resolve = function(promise, x) {
  2753. /* sanity check arguments */
  2754. /* [Promises/A+ 2.3.1] */
  2755. if (promise === x) {
  2756. promise.reject(new TypeError("cannot resolve promise with itself"));
  2757. return;
  2758. }
  2759. /* surgically check for a 'then' method
  2760. (mainly to just call the 'getter' of 'then' only once) */
  2761. var then;
  2762. if (typeof x === "object" && x !== null || typeof x === "function") {
  2763. try {
  2764. then = x.then;
  2765. } /* [Promises/A+ 2.3.3.1, 3.5] */
  2766. catch (e) {
  2767. promise.reject(e);
  2768. /* [Promises/A+ 2.3.3.2] */
  2769. return;
  2770. }
  2771. }
  2772. /* handle own Thenables [Promises/A+ 2.3.2]
  2773. and similar 'thenables' [Promises/A+ 2.3.3] */
  2774. if (typeof then === "function") {
  2775. var resolved = false;
  2776. try {
  2777. /* call retrieved 'then' method */
  2778. /* [Promises/A+ 2.3.3.3] */
  2779. then.call(x, /* resolvePromise */
  2780. /* [Promises/A+ 2.3.3.3.1] */
  2781. function(y) {
  2782. if (resolved) return;
  2783. resolved = true;
  2784. /* [Promises/A+ 2.3.3.3.3] */
  2785. if (y === x) /* [Promises/A+ 3.6] */
  2786. promise.reject(new TypeError("circular thenable chain")); else resolve(promise, y);
  2787. }, /* rejectPromise */
  2788. /* [Promises/A+ 2.3.3.3.2] */
  2789. function(r) {
  2790. if (resolved) return;
  2791. resolved = true;
  2792. /* [Promises/A+ 2.3.3.3.3] */
  2793. promise.reject(r);
  2794. });
  2795. } catch (e) {
  2796. if (!resolved) /* [Promises/A+ 2.3.3.3.3] */
  2797. promise.reject(e);
  2798. }
  2799. return;
  2800. }
  2801. /* handle other values */
  2802. promise.fulfill(x);
  2803. };
  2804. Promise.resolve = function(value) {
  2805. return new Promise(function(resolve) {
  2806. resolve(value);
  2807. });
  2808. };
  2809. Promise.reject = function(reason) {
  2810. return new Promise(function(resolve, reject) {
  2811. reject(reason);
  2812. });
  2813. };
  2814. /* export API */
  2815. module.exports = Promise;
  2816. }
  2817. };
  2818. //src/core/readonly.js
  2819. /**
  2820. * @fileOverview
  2821. *
  2822. * 只读模式支持
  2823. *
  2824. * @author: techird
  2825. * @copyright: Baidu FEX, 2014
  2826. */
  2827. _p[26] = {
  2828. value: function(require, exports, module) {
  2829. var kity = _p.r(17);
  2830. var Minder = _p.r(19);
  2831. var MinderEvent = _p.r(13);
  2832. Minder.registerInitHook(function(options) {
  2833. if (options.readOnly) {
  2834. this.setDisabled();
  2835. }
  2836. });
  2837. kity.extendClass(Minder, {
  2838. disable: function() {
  2839. var me = this;
  2840. //禁用命令
  2841. me.bkqueryCommandState = me.queryCommandState;
  2842. me.bkqueryCommandValue = me.queryCommandValue;
  2843. me.queryCommandState = function(type) {
  2844. var cmd = this._getCommand(type);
  2845. if (cmd && cmd.enableReadOnly) {
  2846. return me.bkqueryCommandState.apply(me, arguments);
  2847. }
  2848. return -1;
  2849. };
  2850. me.queryCommandValue = function(type) {
  2851. var cmd = this._getCommand(type);
  2852. if (cmd && cmd.enableReadOnly) {
  2853. return me.bkqueryCommandValue.apply(me, arguments);
  2854. }
  2855. return null;
  2856. };
  2857. this.setStatus("readonly");
  2858. me._interactChange();
  2859. },
  2860. enable: function() {
  2861. var me = this;
  2862. if (me.bkqueryCommandState) {
  2863. me.queryCommandState = me.bkqueryCommandState;
  2864. delete me.bkqueryCommandState;
  2865. }
  2866. if (me.bkqueryCommandValue) {
  2867. me.queryCommandValue = me.bkqueryCommandValue;
  2868. delete me.bkqueryCommandValue;
  2869. }
  2870. this.setStatus("normal");
  2871. me._interactChange();
  2872. }
  2873. });
  2874. }
  2875. };
  2876. //src/core/render.js
  2877. _p[27] = {
  2878. value: function(require, exports, module) {
  2879. var kity = _p.r(17);
  2880. var Minder = _p.r(19);
  2881. var MinderNode = _p.r(21);
  2882. var Renderer = kity.createClass("Renderer", {
  2883. constructor: function(node) {
  2884. this.node = node;
  2885. },
  2886. create: function(node) {
  2887. throw new Error("Not implement: Renderer.create()");
  2888. },
  2889. shouldRender: function(node) {
  2890. return true;
  2891. },
  2892. watchChange: function(data) {
  2893. var changed;
  2894. if (this.watchingData === undefined) {
  2895. changed = true;
  2896. } else if (this.watchingData != data) {
  2897. changed = true;
  2898. } else {
  2899. changed = false;
  2900. }
  2901. this.watchingData = data;
  2902. },
  2903. shouldDraw: function(node) {
  2904. return true;
  2905. },
  2906. update: function(shape, node, box) {
  2907. if (this.shouldDraw()) this.draw(shape, node);
  2908. return this.place(shape, node, box);
  2909. },
  2910. draw: function(shape, node) {
  2911. throw new Error("Not implement: Renderer.draw()");
  2912. },
  2913. place: function(shape, node, box) {
  2914. throw new Error("Not implement: Renderer.place()");
  2915. },
  2916. getRenderShape: function() {
  2917. return this._renderShape || null;
  2918. },
  2919. setRenderShape: function(shape) {
  2920. this._renderShape = shape;
  2921. }
  2922. });
  2923. function createMinderExtension() {
  2924. function createRendererForNode(node, registered) {
  2925. var renderers = [];
  2926. [ "center", "left", "right", "top", "bottom", "outline", "outside" ].forEach(function(section) {
  2927. var before = "before" + section;
  2928. var after = "after" + section;
  2929. if (registered[before]) {
  2930. renderers = renderers.concat(registered[before]);
  2931. }
  2932. if (registered[section]) {
  2933. renderers = renderers.concat(registered[section]);
  2934. }
  2935. if (registered[after]) {
  2936. renderers = renderers.concat(registered[after]);
  2937. }
  2938. });
  2939. node._renderers = renderers.map(function(Renderer) {
  2940. return new Renderer(node);
  2941. });
  2942. }
  2943. return {
  2944. renderNodeBatch: function(nodes) {
  2945. var rendererClasses = this._rendererClasses;
  2946. var lastBoxes = [];
  2947. var rendererCount = 0;
  2948. var i, j, renderer, node;
  2949. if (!nodes.length) return;
  2950. for (j = 0; j < nodes.length; j++) {
  2951. node = nodes[j];
  2952. if (!node._renderers) {
  2953. createRendererForNode(node, rendererClasses);
  2954. }
  2955. node._contentBox = new kity.Box();
  2956. this.fire("beforerender", {
  2957. node: node
  2958. });
  2959. }
  2960. // 所有节点渲染器数量是一致的
  2961. rendererCount = nodes[0]._renderers.length;
  2962. for (i = 0; i < rendererCount; i++) {
  2963. // 获取延迟盒子数据
  2964. for (j = 0; j < nodes.length; j++) {
  2965. if (typeof lastBoxes[j] == "function") {
  2966. lastBoxes[j] = lastBoxes[j]();
  2967. }
  2968. if (!(lastBoxes[j] instanceof kity.Box)) {
  2969. lastBoxes[j] = new kity.Box(lastBoxes[j]);
  2970. }
  2971. }
  2972. for (j = 0; j < nodes.length; j++) {
  2973. node = nodes[j];
  2974. renderer = node._renderers[i];
  2975. // 合并盒子
  2976. if (lastBoxes[j]) {
  2977. node._contentBox = node._contentBox.merge(lastBoxes[j]);
  2978. renderer.contentBox = lastBoxes[j];
  2979. }
  2980. // 判断当前上下文是否应该渲染
  2981. if (renderer.shouldRender(node)) {
  2982. // 应该渲染,但是渲染图形没创建过,需要创建
  2983. if (!renderer.getRenderShape()) {
  2984. renderer.setRenderShape(renderer.create(node));
  2985. if (renderer.bringToBack) {
  2986. node.getRenderContainer().prependShape(renderer.getRenderShape());
  2987. } else {
  2988. node.getRenderContainer().appendShape(renderer.getRenderShape());
  2989. }
  2990. }
  2991. // 强制让渲染图形显示
  2992. renderer.getRenderShape().setVisible(true);
  2993. // 更新渲染图形
  2994. lastBoxes[j] = renderer.update(renderer.getRenderShape(), node, node._contentBox);
  2995. } else if (renderer.getRenderShape()) {
  2996. renderer.getRenderShape().setVisible(false);
  2997. lastBoxes[j] = null;
  2998. }
  2999. }
  3000. }
  3001. for (j = 0; j < nodes.length; j++) {
  3002. this.fire("noderender", {
  3003. node: nodes[j]
  3004. });
  3005. }
  3006. },
  3007. renderNode: function(node) {
  3008. var rendererClasses = this._rendererClasses;
  3009. var i, latestBox, renderer;
  3010. if (!node._renderers) {
  3011. createRendererForNode(node, rendererClasses);
  3012. }
  3013. this.fire("beforerender", {
  3014. node: node
  3015. });
  3016. node._contentBox = new kity.Box();
  3017. node._renderers.forEach(function(renderer) {
  3018. // 判断当前上下文是否应该渲染
  3019. if (renderer.shouldRender(node)) {
  3020. // 应该渲染,但是渲染图形没创建过,需要创建
  3021. if (!renderer.getRenderShape()) {
  3022. renderer.setRenderShape(renderer.create(node));
  3023. if (renderer.bringToBack) {
  3024. node.getRenderContainer().prependShape(renderer.getRenderShape());
  3025. } else {
  3026. node.getRenderContainer().appendShape(renderer.getRenderShape());
  3027. }
  3028. }
  3029. // 强制让渲染图形显示
  3030. renderer.getRenderShape().setVisible(true);
  3031. // 更新渲染图形
  3032. latestBox = renderer.update(renderer.getRenderShape(), node, node._contentBox);
  3033. if (typeof latestBox == "function") latestBox = latestBox();
  3034. // 合并渲染区域
  3035. if (latestBox) {
  3036. node._contentBox = node._contentBox.merge(latestBox);
  3037. renderer.contentBox = latestBox;
  3038. }
  3039. } else if (renderer.getRenderShape()) {
  3040. renderer.getRenderShape().setVisible(false);
  3041. }
  3042. });
  3043. this.fire("noderender", {
  3044. node: node
  3045. });
  3046. }
  3047. };
  3048. }
  3049. kity.extendClass(Minder, createMinderExtension());
  3050. kity.extendClass(MinderNode, {
  3051. render: function() {
  3052. if (!this.attached) return;
  3053. this.getMinder().renderNode(this);
  3054. return this;
  3055. },
  3056. renderTree: function() {
  3057. if (!this.attached) return;
  3058. var list = [];
  3059. this.traverse(function(node) {
  3060. list.push(node);
  3061. });
  3062. this.getMinder().renderNodeBatch(list);
  3063. return this;
  3064. },
  3065. getRenderer: function(type) {
  3066. var rs = this._renderers;
  3067. if (!rs) return null;
  3068. for (var i = 0; i < rs.length; i++) {
  3069. if (rs[i].getType() == type) return rs[i];
  3070. }
  3071. return null;
  3072. },
  3073. getContentBox: function() {
  3074. //if (!this._contentBox) this.render();
  3075. return this.parent && this.parent.isCollapsed() ? new kity.Box() : this._contentBox || new kity.Box();
  3076. },
  3077. getRenderBox: function(rendererType, refer) {
  3078. var renderer = rendererType && this.getRenderer(rendererType);
  3079. var contentBox = renderer ? renderer.contentBox : this.getContentBox();
  3080. var ctm = kity.Matrix.getCTM(this.getRenderContainer(), refer || "paper");
  3081. return ctm.transformBox(contentBox);
  3082. }
  3083. });
  3084. module.exports = Renderer;
  3085. }
  3086. };
  3087. //src/core/select.js
  3088. _p[28] = {
  3089. value: function(require, exports, module) {
  3090. var kity = _p.r(17);
  3091. var utils = _p.r(33);
  3092. var Minder = _p.r(19);
  3093. var MinderNode = _p.r(21);
  3094. Minder.registerInitHook(function() {
  3095. this._initSelection();
  3096. });
  3097. // 选区管理
  3098. kity.extendClass(Minder, {
  3099. _initSelection: function() {
  3100. this._selectedNodes = [];
  3101. },
  3102. renderChangedSelection: function(last) {
  3103. var current = this.getSelectedNodes();
  3104. var changed = [];
  3105. current.forEach(function(node) {
  3106. if (last.indexOf(node) == -1) {
  3107. changed.push(node);
  3108. }
  3109. });
  3110. last.forEach(function(node) {
  3111. if (current.indexOf(node) == -1) {
  3112. changed.push(node);
  3113. }
  3114. });
  3115. if (changed.length) {
  3116. this._interactChange();
  3117. this.fire("selectionchange");
  3118. }
  3119. while (changed.length) {
  3120. changed.shift().render();
  3121. }
  3122. },
  3123. getSelectedNodes: function() {
  3124. //不能克隆返回,会对当前选区操作,从而影响querycommand
  3125. return this._selectedNodes;
  3126. },
  3127. getSelectedNode: function() {
  3128. return this.getSelectedNodes()[0] || null;
  3129. },
  3130. removeAllSelectedNodes: function() {
  3131. var me = this;
  3132. var last = this._selectedNodes.splice(0);
  3133. this._selectedNodes = [];
  3134. this.renderChangedSelection(last);
  3135. return this.fire("selectionclear");
  3136. },
  3137. removeSelectedNodes: function(nodes) {
  3138. var me = this;
  3139. var last = this._selectedNodes.slice(0);
  3140. nodes = utils.isArray(nodes) ? nodes : [ nodes ];
  3141. nodes.forEach(function(node) {
  3142. var index;
  3143. if ((index = me._selectedNodes.indexOf(node)) === -1) return;
  3144. me._selectedNodes.splice(index, 1);
  3145. });
  3146. this.renderChangedSelection(last);
  3147. return this;
  3148. },
  3149. select: function(nodes, isSingleSelect) {
  3150. var lastSelect = this.getSelectedNodes().slice(0);
  3151. if (isSingleSelect) {
  3152. this._selectedNodes = [];
  3153. }
  3154. var me = this;
  3155. nodes = utils.isArray(nodes) ? nodes : [ nodes ];
  3156. nodes.forEach(function(node) {
  3157. if (me._selectedNodes.indexOf(node) !== -1) return;
  3158. me._selectedNodes.unshift(node);
  3159. });
  3160. this.renderChangedSelection(lastSelect);
  3161. return this;
  3162. },
  3163. selectById: function(ids, isSingleSelect) {
  3164. ids = utils.isArray(ids) ? ids : [ ids ];
  3165. var nodes = this.getNodesById(ids);
  3166. return this.select(nodes, isSingleSelect);
  3167. },
  3168. //当前选区中的节点在给定的节点范围内的保留选中状态,
  3169. //没在给定范围的取消选中,给定范围中的但没在当前选中范围的也做选中效果
  3170. toggleSelect: function(node) {
  3171. if (utils.isArray(node)) {
  3172. node.forEach(this.toggleSelect.bind(this));
  3173. } else {
  3174. if (node.isSelected()) this.removeSelectedNodes(node); else this.select(node);
  3175. }
  3176. return this;
  3177. },
  3178. isSingleSelect: function() {
  3179. return this._selectedNodes.length == 1;
  3180. },
  3181. getSelectedAncestors: function(includeRoot) {
  3182. var nodes = this.getSelectedNodes().slice(0), ancestors = [], judge;
  3183. // 根节点不参与计算
  3184. var rootIndex = nodes.indexOf(this.getRoot());
  3185. if (~rootIndex && !includeRoot) {
  3186. nodes.splice(rootIndex, 1);
  3187. }
  3188. // 判断 nodes 列表中是否存在 judge 的祖先
  3189. function hasAncestor(nodes, judge) {
  3190. for (var i = nodes.length - 1; i >= 0; --i) {
  3191. if (nodes[i].isAncestorOf(judge)) return true;
  3192. }
  3193. return false;
  3194. }
  3195. // 按照拓扑排序
  3196. nodes.sort(function(node1, node2) {
  3197. return node1.getLevel() - node2.getLevel();
  3198. });
  3199. // 因为是拓扑有序的,所以只需往上查找
  3200. while (judge = nodes.pop()) {
  3201. if (!hasAncestor(nodes, judge)) {
  3202. ancestors.push(judge);
  3203. }
  3204. }
  3205. return ancestors;
  3206. }
  3207. });
  3208. kity.extendClass(MinderNode, {
  3209. isSelected: function() {
  3210. var minder = this.getMinder();
  3211. return minder && minder.getSelectedNodes().indexOf(this) != -1;
  3212. }
  3213. });
  3214. }
  3215. };
  3216. //src/core/shortcut.js
  3217. /**
  3218. * @fileOverview
  3219. *
  3220. * 添加快捷键支持
  3221. *
  3222. * @author: techird
  3223. * @copyright: Baidu FEX, 2014
  3224. */
  3225. _p[29] = {
  3226. value: function(require, exports, module) {
  3227. var kity = _p.r(17);
  3228. var utils = _p.r(33);
  3229. var keymap = _p.r(15);
  3230. var Minder = _p.r(19);
  3231. var MinderEvent = _p.r(13);
  3232. /**
  3233. * 计算包含 meta 键的 keycode
  3234. *
  3235. * @param {String|KeyEvent} unknown
  3236. */
  3237. function getMetaKeyCode(unknown) {
  3238. var CTRL_MASK = 4096;
  3239. var ALT_MASK = 8192;
  3240. var SHIFT_MASK = 16384;
  3241. var metaKeyCode = 0;
  3242. if (typeof unknown == "string") {
  3243. // unknown as string
  3244. unknown.toLowerCase().split(/\+\s*/).forEach(function(name) {
  3245. switch (name) {
  3246. case "ctrl":
  3247. case "cmd":
  3248. metaKeyCode |= CTRL_MASK;
  3249. break;
  3250. case "alt":
  3251. metaKeyCode |= ALT_MASK;
  3252. break;
  3253. case "shift":
  3254. metaKeyCode |= SHIFT_MASK;
  3255. break;
  3256. default:
  3257. metaKeyCode |= keymap[name];
  3258. }
  3259. });
  3260. } else {
  3261. // unknown as key event
  3262. if (unknown.ctrlKey || unknown.metaKey) {
  3263. metaKeyCode |= CTRL_MASK;
  3264. }
  3265. if (unknown.altKey) {
  3266. metaKeyCode |= ALT_MASK;
  3267. }
  3268. if (unknown.shiftKey) {
  3269. metaKeyCode |= SHIFT_MASK;
  3270. }
  3271. metaKeyCode |= unknown.keyCode;
  3272. }
  3273. return metaKeyCode;
  3274. }
  3275. kity.extendClass(MinderEvent, {
  3276. isShortcutKey: function(keyCombine) {
  3277. var keyEvent = this.originEvent;
  3278. if (!keyEvent) return false;
  3279. return getMetaKeyCode(keyCombine) == getMetaKeyCode(keyEvent);
  3280. }
  3281. });
  3282. Minder.registerInitHook(function() {
  3283. this._initShortcutKey();
  3284. });
  3285. kity.extendClass(Minder, {
  3286. _initShortcutKey: function() {
  3287. this._bindShortcutKeys();
  3288. },
  3289. _bindShortcutKeys: function() {
  3290. var map = this._shortcutKeys = {};
  3291. var has = "hasOwnProperty";
  3292. this.on("keydown", function(e) {
  3293. for (var keys in map) {
  3294. if (!map[has](keys)) continue;
  3295. if (e.isShortcutKey(keys)) {
  3296. var fn = map[keys];
  3297. if (fn.__statusCondition && fn.__statusCondition != this.getStatus()) return;
  3298. fn();
  3299. e.preventDefault();
  3300. }
  3301. }
  3302. });
  3303. },
  3304. addShortcut: function(keys, fn) {
  3305. var binds = this._shortcutKeys;
  3306. keys.split(/\|\s*/).forEach(function(combine) {
  3307. var parts = combine.split("::");
  3308. var status;
  3309. if (parts.length > 1) {
  3310. combine = parts[1];
  3311. status = parts[0];
  3312. fn.__statusCondition = status;
  3313. }
  3314. binds[combine] = fn;
  3315. });
  3316. },
  3317. addCommandShortcutKeys: function(cmd, keys) {
  3318. var binds = this._commandShortcutKeys || (this._commandShortcutKeys = {});
  3319. var obj = {}, km = this;
  3320. if (keys) {
  3321. obj[cmd] = keys;
  3322. } else {
  3323. obj = cmd;
  3324. }
  3325. var minder = this;
  3326. utils.each(obj, function(keys, command) {
  3327. binds[command] = keys;
  3328. minder.addShortcut(keys, function execCommandByShortcut() {
  3329. /**
  3330. * 之前判断有问题,由 === 0 改为 !== -1
  3331. * @editor Naixor
  3332. * @Date 2015-12-2
  3333. */
  3334. if (minder.queryCommandState(command) !== -1) {
  3335. minder.execCommand(command);
  3336. }
  3337. });
  3338. });
  3339. },
  3340. getCommandShortcutKey: function(cmd) {
  3341. var binds = this._commandShortcutKeys;
  3342. return binds && binds[cmd] || null;
  3343. },
  3344. /**
  3345. * @Desc: 添加一个判断是否支持原生Clipboard的变量,用于对ctrl + v和ctrl + c的处理
  3346. * @Editor: Naixor
  3347. * @Date: 2015.9.20
  3348. */
  3349. supportClipboardEvent: function(window) {
  3350. return !!window.ClipboardEvent;
  3351. }(window)
  3352. });
  3353. }
  3354. };
  3355. //src/core/status.js
  3356. /**
  3357. * @fileOverview
  3358. *
  3359. * 状态切换控制
  3360. *
  3361. * @author: techird
  3362. * @copyright: Baidu FEX, 2014
  3363. */
  3364. _p[30] = {
  3365. value: function(require, exports, module) {
  3366. var kity = _p.r(17);
  3367. var Minder = _p.r(19);
  3368. var sf = ~window.location.href.indexOf("status");
  3369. var tf = ~window.location.href.indexOf("trace");
  3370. Minder.registerInitHook(function() {
  3371. this._initStatus();
  3372. });
  3373. kity.extendClass(Minder, {
  3374. _initStatus: function() {
  3375. this._status = "normal";
  3376. this._rollbackStatus = "normal";
  3377. },
  3378. setStatus: function(status, force) {
  3379. // 在 readonly 模式下,只有 force 为 true 才能切换回来
  3380. if (this._status == "readonly" && !force) return this;
  3381. if (status != this._status) {
  3382. this._rollbackStatus = this._status;
  3383. this._status = status;
  3384. this.fire("statuschange", {
  3385. lastStatus: this._rollbackStatus,
  3386. currentStatus: this._status
  3387. });
  3388. if (sf) {
  3389. /* global console: true */
  3390. console.log(window.event.type, this._rollbackStatus, "->", this._status);
  3391. if (tf) {
  3392. console.trace();
  3393. }
  3394. }
  3395. }
  3396. return this;
  3397. },
  3398. rollbackStatus: function() {
  3399. this.setStatus(this._rollbackStatus);
  3400. },
  3401. getRollbackStatus: function() {
  3402. return this._rollbackStatus;
  3403. },
  3404. getStatus: function() {
  3405. return this._status;
  3406. }
  3407. });
  3408. }
  3409. };
  3410. //src/core/template.js
  3411. _p[31] = {
  3412. value: function(require, exports, module) {
  3413. var kity = _p.r(17);
  3414. var utils = _p.r(33);
  3415. var Minder = _p.r(19);
  3416. var Command = _p.r(9);
  3417. var MinderNode = _p.r(21);
  3418. var Module = _p.r(20);
  3419. var _templates = {};
  3420. function register(name, supports) {
  3421. _templates[name] = supports;
  3422. }
  3423. exports.register = register;
  3424. utils.extend(Minder, {
  3425. getTemplateList: function() {
  3426. return _templates;
  3427. }
  3428. });
  3429. kity.extendClass(Minder, function() {
  3430. var originGetTheme = Minder.prototype.getTheme;
  3431. return {
  3432. useTemplate: function(name, duration) {
  3433. this.setTemplate(name);
  3434. this.refresh(duration || 800);
  3435. },
  3436. getTemplate: function() {
  3437. return this._template || "default";
  3438. },
  3439. setTemplate: function(name) {
  3440. this._template = name || null;
  3441. },
  3442. getTemplateSupport: function(method) {
  3443. var supports = _templates[this.getTemplate()];
  3444. return supports && supports[method];
  3445. },
  3446. getTheme: function(node) {
  3447. var support = this.getTemplateSupport("getTheme") || originGetTheme;
  3448. return support.call(this, node);
  3449. }
  3450. };
  3451. }());
  3452. kity.extendClass(MinderNode, function() {
  3453. var originGetLayout = MinderNode.prototype.getLayout;
  3454. var originGetConnect = MinderNode.prototype.getConnect;
  3455. return {
  3456. getLayout: function() {
  3457. var support = this.getMinder().getTemplateSupport("getLayout") || originGetLayout;
  3458. return support.call(this, this);
  3459. },
  3460. getConnect: function() {
  3461. var support = this.getMinder().getTemplateSupport("getConnect") || originGetConnect;
  3462. return support.call(this, this);
  3463. }
  3464. };
  3465. }());
  3466. Module.register("TemplateModule", {
  3467. /**
  3468. * @command Template
  3469. * @description 设置当前脑图的模板
  3470. * @param {string} name 模板名称
  3471. * 允许使用的模板可以使用 `kityminder.Minder.getTemplateList()` 查询
  3472. * @state
  3473. * 0: 始终可用
  3474. * @return 返回当前的模板名称
  3475. */
  3476. commands: {
  3477. template: kity.createClass("TemplateCommand", {
  3478. base: Command,
  3479. execute: function(minder, name) {
  3480. minder.useTemplate(name);
  3481. minder.execCommand("camera");
  3482. },
  3483. queryValue: function(minder) {
  3484. return minder.getTemplate() || "default";
  3485. }
  3486. })
  3487. }
  3488. });
  3489. }
  3490. };
  3491. //src/core/theme.js
  3492. _p[32] = {
  3493. value: function(require, exports, module) {
  3494. var kity = _p.r(17);
  3495. var utils = _p.r(33);
  3496. var Minder = _p.r(19);
  3497. var MinderNode = _p.r(21);
  3498. var Module = _p.r(20);
  3499. var Command = _p.r(9);
  3500. var cssLikeValueMatcher = {
  3501. left: function(value) {
  3502. return 3 in value && value[3] || 1 in value && value[1] || value[0];
  3503. },
  3504. right: function(value) {
  3505. return 1 in value && value[1] || value[0];
  3506. },
  3507. top: function(value) {
  3508. return value[0];
  3509. },
  3510. bottom: function(value) {
  3511. return 2 in value && value[2] || value[0];
  3512. }
  3513. };
  3514. var _themes = {};
  3515. /**
  3516. * 注册一个主题
  3517. *
  3518. * @param {String} name 主题的名称
  3519. * @param {Plain} theme 主题的样式描述
  3520. *
  3521. * @example
  3522. * Minder.registerTheme('default', {
  3523. * 'root-color': 'red',
  3524. * 'root-stroke': 'none',
  3525. * 'root-padding': [10, 20]
  3526. * });
  3527. */
  3528. function register(name, theme) {
  3529. _themes[name] = theme;
  3530. }
  3531. exports.register = register;
  3532. utils.extend(Minder, {
  3533. getThemeList: function() {
  3534. return _themes;
  3535. }
  3536. });
  3537. kity.extendClass(Minder, {
  3538. /**
  3539. * 切换脑图实例上的主题
  3540. * @param {String} name 要使用的主题的名称
  3541. */
  3542. useTheme: function(name) {
  3543. this.setTheme(name);
  3544. this.refresh(800);
  3545. return true;
  3546. },
  3547. setTheme: function(name) {
  3548. if (name && !_themes[name]) throw new Error("Theme " + name + " not exists!");
  3549. var lastTheme = this._theme;
  3550. this._theme = name || null;
  3551. var container = this.getRenderTarget();
  3552. if (container) {
  3553. container.classList.remove("km-theme-" + lastTheme);
  3554. if (name) {
  3555. container.classList.add("km-theme-" + name);
  3556. }
  3557. container.style.background = this.getStyle("background");
  3558. }
  3559. this.fire("themechange", {
  3560. theme: name
  3561. });
  3562. return this;
  3563. },
  3564. /**
  3565. * 获取脑图实例上的当前主题
  3566. * @return {[type]} [description]
  3567. */
  3568. getTheme: function(node) {
  3569. return this._theme || this.getOption("defaultTheme") || "fresh-blue";
  3570. },
  3571. getThemeItems: function(node) {
  3572. var theme = this.getTheme(node);
  3573. return _themes[this.getTheme(node)];
  3574. },
  3575. /**
  3576. * 获得脑图实例上的样式
  3577. * @param {String} item 样式名称
  3578. */
  3579. getStyle: function(item, node) {
  3580. var items = this.getThemeItems(node);
  3581. var segment, dir, selector, value, matcher;
  3582. if (item in items) return items[item];
  3583. // 尝试匹配 CSS 数组形式的值
  3584. // 比如 item 为 'pading-left'
  3585. // theme 里有 {'padding': [10, 20]} 的定义,则可以返回 20
  3586. segment = item.split("-");
  3587. if (segment.length < 2) return null;
  3588. dir = segment.pop();
  3589. item = segment.join("-");
  3590. if (item in items) {
  3591. value = items[item];
  3592. if (utils.isArray(value) && (matcher = cssLikeValueMatcher[dir])) {
  3593. return matcher(value);
  3594. }
  3595. if (!isNaN(value)) return value;
  3596. }
  3597. return null;
  3598. },
  3599. /**
  3600. * 获取指定节点的样式
  3601. * @param {String} name 样式名称,可以不加节点类型的前缀
  3602. */
  3603. getNodeStyle: function(node, name) {
  3604. var value = this.getStyle(node.getType() + "-" + name, node);
  3605. return value !== null ? value : this.getStyle(name, node);
  3606. }
  3607. });
  3608. kity.extendClass(MinderNode, {
  3609. getStyle: function(name) {
  3610. return this.getMinder().getNodeStyle(this, name);
  3611. }
  3612. });
  3613. Module.register("Theme", {
  3614. defaultOptions: {
  3615. defaultTheme: "fresh-blue"
  3616. },
  3617. commands: {
  3618. /**
  3619. * @command Theme
  3620. * @description 设置当前脑图的主题
  3621. * @param {string} name 主题名称
  3622. * 允许使用的主题可以使用 `kityminder.Minder.getThemeList()` 查询
  3623. * @state
  3624. * 0: 始终可用
  3625. * @return 返回当前的主题名称
  3626. */
  3627. theme: kity.createClass("ThemeCommand", {
  3628. base: Command,
  3629. execute: function(km, name) {
  3630. return km.useTheme(name);
  3631. },
  3632. queryValue: function(km) {
  3633. return km.getTheme() || "default";
  3634. }
  3635. })
  3636. }
  3637. });
  3638. Minder.registerInitHook(function() {
  3639. this.setTheme();
  3640. });
  3641. }
  3642. };
  3643. //src/core/utils.js
  3644. _p[33] = {
  3645. value: function(require, exports) {
  3646. var kity = _p.r(17);
  3647. var uuidMap = {};
  3648. exports.extend = kity.Utils.extend.bind(kity.Utils);
  3649. exports.each = kity.Utils.each.bind(kity.Utils);
  3650. exports.uuid = function(group) {
  3651. uuidMap[group] = uuidMap[group] ? uuidMap[group] + 1 : 1;
  3652. return group + uuidMap[group];
  3653. };
  3654. exports.guid = function() {
  3655. return (+new Date() * 1e6 + Math.floor(Math.random() * 1e6)).toString(36);
  3656. };
  3657. exports.trim = function(str) {
  3658. return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, "");
  3659. };
  3660. exports.keys = function(plain) {
  3661. var keys = [];
  3662. for (var key in plain) {
  3663. if (plain.hasOwnProperty(key)) {
  3664. keys.push(key);
  3665. }
  3666. }
  3667. return keys;
  3668. };
  3669. exports.clone = function(source) {
  3670. return JSON.parse(JSON.stringify(source));
  3671. };
  3672. exports.comparePlainObject = function(a, b) {
  3673. return JSON.stringify(a) == JSON.stringify(b);
  3674. };
  3675. exports.encodeHtml = function(str, reg) {
  3676. return str ? str.replace(reg || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g, function(a, b) {
  3677. if (b) {
  3678. return a;
  3679. } else {
  3680. return {
  3681. "<": "&lt;",
  3682. "&": "&amp;",
  3683. '"': "&quot;",
  3684. ">": "&gt;",
  3685. "'": "&#39;"
  3686. }[a];
  3687. }
  3688. }) : "";
  3689. };
  3690. exports.clearWhiteSpace = function(str) {
  3691. return str.replace(/[\u200b\t\r\n]/g, "");
  3692. };
  3693. exports.each([ "String", "Function", "Array", "Number", "RegExp", "Object" ], function(v) {
  3694. var toString = Object.prototype.toString;
  3695. exports["is" + v] = function(obj) {
  3696. return toString.apply(obj) == "[object " + v + "]";
  3697. };
  3698. });
  3699. }
  3700. };
  3701. //src/expose-kityminder.js
  3702. _p[34] = {
  3703. value: function(require, exports, module) {
  3704. module.exports = window.kityminder = _p.r(35);
  3705. }
  3706. };
  3707. //src/kityminder.js
  3708. /**
  3709. * @fileOverview
  3710. *
  3711. * 默认导出(全部模块)
  3712. *
  3713. * @author: techird
  3714. * @copyright: Baidu FEX, 2014
  3715. */
  3716. _p[35] = {
  3717. value: function(require, exports, module) {
  3718. var kityminder = {
  3719. version: _p.r(19).version
  3720. };
  3721. // 核心导出,大写的部分导出类,小写的部分简单 require 一下
  3722. // 这里顺序是有讲究的,调整前先弄清楚依赖关系。
  3723. _p.r(33);
  3724. kityminder.Minder = _p.r(19);
  3725. kityminder.Command = _p.r(9);
  3726. kityminder.Node = _p.r(21);
  3727. _p.r(22);
  3728. _p.r(8);
  3729. kityminder.Event = _p.r(13);
  3730. kityminder.data = _p.r(12);
  3731. _p.r(10);
  3732. kityminder.KeyMap = _p.r(15);
  3733. _p.r(29);
  3734. _p.r(30);
  3735. _p.r(23);
  3736. _p.r(28);
  3737. _p.r(14);
  3738. _p.r(16);
  3739. kityminder.Module = _p.r(20);
  3740. _p.r(26);
  3741. kityminder.Render = _p.r(27);
  3742. kityminder.Connect = _p.r(11);
  3743. kityminder.Layout = _p.r(18);
  3744. kityminder.Theme = _p.r(32);
  3745. kityminder.Template = _p.r(31);
  3746. kityminder.Promise = _p.r(25);
  3747. _p.r(7);
  3748. _p.r(24);
  3749. // 模块依赖
  3750. _p.r(42);
  3751. _p.r(43);
  3752. _p.r(44);
  3753. _p.r(45);
  3754. _p.r(46);
  3755. _p.r(47);
  3756. _p.r(48);
  3757. _p.r(50);
  3758. _p.r(49);
  3759. _p.r(51);
  3760. _p.r(52);
  3761. _p.r(53);
  3762. _p.r(54);
  3763. _p.r(55);
  3764. _p.r(56);
  3765. _p.r(57);
  3766. _p.r(58);
  3767. _p.r(59);
  3768. _p.r(60);
  3769. _p.r(61);
  3770. _p.r(62);
  3771. _p.r(63);
  3772. _p.r(64);
  3773. _p.r(68);
  3774. _p.r(65);
  3775. _p.r(67);
  3776. _p.r(66);
  3777. _p.r(40);
  3778. _p.r(36);
  3779. _p.r(37);
  3780. _p.r(38);
  3781. _p.r(39);
  3782. _p.r(41);
  3783. _p.r(75);
  3784. _p.r(78);
  3785. _p.r(77);
  3786. _p.r(76);
  3787. _p.r(78);
  3788. _p.r(80);
  3789. _p.r(79);
  3790. _p.r(0);
  3791. _p.r(1);
  3792. _p.r(2);
  3793. _p.r(3);
  3794. _p.r(4);
  3795. _p.r(5);
  3796. _p.r(6);
  3797. _p.r(69);
  3798. _p.r(73);
  3799. _p.r(70);
  3800. _p.r(72);
  3801. _p.r(71);
  3802. _p.r(74);
  3803. module.exports = kityminder;
  3804. }
  3805. };
  3806. //src/layout/btree.js
  3807. _p[36] = {
  3808. value: function(require, exports, module) {
  3809. var kity = _p.r(17);
  3810. var Layout = _p.r(18);
  3811. [ "left", "right", "top", "bottom" ].forEach(registerLayoutForDirection);
  3812. function registerLayoutForDirection(name) {
  3813. var axis = name == "left" || name == "right" ? "x" : "y";
  3814. var dir = name == "left" || name == "top" ? -1 : 1;
  3815. var oppsite = {
  3816. left: "right",
  3817. right: "left",
  3818. top: "bottom",
  3819. bottom: "top",
  3820. x: "y",
  3821. y: "x"
  3822. };
  3823. function getOrderHint(node) {
  3824. var hint = [];
  3825. var box = node.getLayoutBox();
  3826. var offset = 5;
  3827. if (axis == "x") {
  3828. hint.push({
  3829. type: "up",
  3830. node: node,
  3831. area: new kity.Box({
  3832. x: box.x,
  3833. y: box.top - node.getStyle("margin-top") - offset,
  3834. width: box.width,
  3835. height: node.getStyle("margin-top")
  3836. }),
  3837. path: [ "M", box.x, box.top - offset, "L", box.right, box.top - offset ]
  3838. });
  3839. hint.push({
  3840. type: "down",
  3841. node: node,
  3842. area: new kity.Box({
  3843. x: box.x,
  3844. y: box.bottom + offset,
  3845. width: box.width,
  3846. height: node.getStyle("margin-bottom")
  3847. }),
  3848. path: [ "M", box.x, box.bottom + offset, "L", box.right, box.bottom + offset ]
  3849. });
  3850. } else {
  3851. hint.push({
  3852. type: "up",
  3853. node: node,
  3854. area: new kity.Box({
  3855. x: box.left - node.getStyle("margin-left") - offset,
  3856. y: box.top,
  3857. width: node.getStyle("margin-left"),
  3858. height: box.height
  3859. }),
  3860. path: [ "M", box.left - offset, box.top, "L", box.left - offset, box.bottom ]
  3861. });
  3862. hint.push({
  3863. type: "down",
  3864. node: node,
  3865. area: new kity.Box({
  3866. x: box.right + offset,
  3867. y: box.top,
  3868. width: node.getStyle("margin-right"),
  3869. height: box.height
  3870. }),
  3871. path: [ "M", box.right + offset, box.top, "L", box.right + offset, box.bottom ]
  3872. });
  3873. }
  3874. return hint;
  3875. }
  3876. Layout.register(name, kity.createClass({
  3877. base: Layout,
  3878. doLayout: function(parent, children) {
  3879. var pbox = parent.getContentBox();
  3880. if (axis == "x") {
  3881. parent.setVertexOut(new kity.Point(pbox[name], pbox.cy));
  3882. parent.setLayoutVectorOut(new kity.Vector(dir, 0));
  3883. } else {
  3884. parent.setVertexOut(new kity.Point(pbox.cx, pbox[name]));
  3885. parent.setLayoutVectorOut(new kity.Vector(0, dir));
  3886. }
  3887. if (!children.length) {
  3888. return false;
  3889. }
  3890. children.forEach(function(child) {
  3891. var cbox = child.getContentBox();
  3892. child.setLayoutTransform(new kity.Matrix());
  3893. if (axis == "x") {
  3894. child.setVertexIn(new kity.Point(cbox[oppsite[name]], cbox.cy));
  3895. child.setLayoutVectorIn(new kity.Vector(dir, 0));
  3896. } else {
  3897. child.setVertexIn(new kity.Point(cbox.cx, cbox[oppsite[name]]));
  3898. child.setLayoutVectorIn(new kity.Vector(0, dir));
  3899. }
  3900. });
  3901. this.align(children, oppsite[name]);
  3902. this.stack(children, oppsite[axis]);
  3903. var bbox = this.getBranchBox(children);
  3904. var xAdjust = 0, yAdjust = 0;
  3905. if (axis == "x") {
  3906. xAdjust = pbox[name];
  3907. xAdjust += dir * parent.getStyle("margin-" + name);
  3908. xAdjust += dir * children[0].getStyle("margin-" + oppsite[name]);
  3909. yAdjust = pbox.bottom;
  3910. yAdjust -= pbox.height / 2;
  3911. yAdjust -= bbox.height / 2;
  3912. yAdjust -= bbox.y;
  3913. } else {
  3914. xAdjust = pbox.right;
  3915. xAdjust -= pbox.width / 2;
  3916. xAdjust -= bbox.width / 2;
  3917. xAdjust -= bbox.x;
  3918. yAdjust = pbox[name];
  3919. yAdjust += dir * parent.getStyle("margin-" + name);
  3920. yAdjust += dir * children[0].getStyle("margin-" + oppsite[name]);
  3921. }
  3922. this.move(children, xAdjust, yAdjust);
  3923. },
  3924. getOrderHint: getOrderHint
  3925. }));
  3926. }
  3927. }
  3928. };
  3929. //src/layout/filetree.js
  3930. _p[37] = {
  3931. value: function(require, exports, module) {
  3932. var kity = _p.r(17);
  3933. var Layout = _p.r(18);
  3934. [ -1, 1 ].forEach(registerLayoutForDir);
  3935. function registerLayoutForDir(dir) {
  3936. var name = "filetree-" + (dir > 0 ? "down" : "up");
  3937. Layout.register(name, kity.createClass({
  3938. base: Layout,
  3939. doLayout: function(parent, children, round) {
  3940. var pBox = parent.getContentBox();
  3941. var indent = 20;
  3942. parent.setVertexOut(new kity.Point(pBox.left + indent, dir > 0 ? pBox.bottom : pBox.top));
  3943. parent.setLayoutVectorOut(new kity.Vector(0, dir));
  3944. if (!children.length) return;
  3945. children.forEach(function(child) {
  3946. var cbox = child.getContentBox();
  3947. child.setLayoutTransform(new kity.Matrix());
  3948. child.setVertexIn(new kity.Point(cbox.left, cbox.cy));
  3949. child.setLayoutVectorIn(new kity.Vector(1, 0));
  3950. });
  3951. this.align(children, "left");
  3952. this.stack(children, "y");
  3953. var xAdjust = 0;
  3954. xAdjust += pBox.left;
  3955. xAdjust += indent;
  3956. xAdjust += children[0].getStyle("margin-left");
  3957. var yAdjust = 0;
  3958. if (dir > 0) {
  3959. yAdjust += pBox.bottom;
  3960. yAdjust += parent.getStyle("margin-bottom");
  3961. yAdjust += children[0].getStyle("margin-top");
  3962. } else {
  3963. yAdjust -= this.getTreeBox(children).bottom;
  3964. yAdjust += pBox.top;
  3965. yAdjust -= parent.getStyle("margin-top");
  3966. yAdjust -= children[0].getStyle("margin-bottom");
  3967. }
  3968. this.move(children, xAdjust, yAdjust);
  3969. },
  3970. getOrderHint: function(node) {
  3971. var hint = [];
  3972. var box = node.getLayoutBox();
  3973. var offset = node.getLevel() > 1 ? 3 : 5;
  3974. hint.push({
  3975. type: "up",
  3976. node: node,
  3977. area: new kity.Box({
  3978. x: box.x,
  3979. y: box.top - node.getStyle("margin-top") - offset,
  3980. width: box.width,
  3981. height: node.getStyle("margin-top")
  3982. }),
  3983. path: [ "M", box.x, box.top - offset, "L", box.right, box.top - offset ]
  3984. });
  3985. hint.push({
  3986. type: "down",
  3987. node: node,
  3988. area: new kity.Box({
  3989. x: box.x,
  3990. y: box.bottom + offset,
  3991. width: box.width,
  3992. height: node.getStyle("margin-bottom")
  3993. }),
  3994. path: [ "M", box.x, box.bottom + offset, "L", box.right, box.bottom + offset ]
  3995. });
  3996. return hint;
  3997. }
  3998. }));
  3999. }
  4000. }
  4001. };
  4002. //src/layout/fish-bone-master.js
  4003. /**
  4004. * @fileOverview
  4005. *
  4006. * 鱼骨图主骨架布局
  4007. *
  4008. * @author: techird
  4009. * @copyright: Baidu FEX, 2014
  4010. */
  4011. _p[38] = {
  4012. value: function(require, exports, module) {
  4013. var kity = _p.r(17);
  4014. var Layout = _p.r(18);
  4015. Layout.register("fish-bone-master", kity.createClass("FishBoneMasterLayout", {
  4016. base: Layout,
  4017. doLayout: function(parent, children, round) {
  4018. var upPart = [], downPart = [];
  4019. var child = children[0];
  4020. var pBox = parent.getContentBox();
  4021. parent.setVertexOut(new kity.Point(pBox.right, pBox.cy));
  4022. parent.setLayoutVectorOut(new kity.Vector(1, 0));
  4023. if (!child) return;
  4024. var cBox = child.getContentBox();
  4025. var pMarginRight = parent.getStyle("margin-right");
  4026. var cMarginLeft = child.getStyle("margin-left");
  4027. var cMarginTop = child.getStyle("margin-top");
  4028. var cMarginBottom = child.getStyle("margin-bottom");
  4029. children.forEach(function(child, index) {
  4030. child.setLayoutTransform(new kity.Matrix());
  4031. var cBox = child.getContentBox();
  4032. if (index % 2) {
  4033. downPart.push(child);
  4034. child.setVertexIn(new kity.Point(cBox.left, cBox.top));
  4035. child.setLayoutVectorIn(new kity.Vector(1, 1));
  4036. } else {
  4037. upPart.push(child);
  4038. child.setVertexIn(new kity.Point(cBox.left, cBox.bottom));
  4039. child.setLayoutVectorIn(new kity.Vector(1, -1));
  4040. }
  4041. });
  4042. this.stack(upPart, "x");
  4043. this.stack(downPart, "x");
  4044. this.align(upPart, "bottom");
  4045. this.align(downPart, "top");
  4046. var xAdjust = pBox.right + pMarginRight + cMarginLeft;
  4047. var yAdjustUp = pBox.cy - cMarginBottom - parent.getStyle("margin-top");
  4048. var yAdjustDown = pBox.cy + cMarginTop + parent.getStyle("margin-bottom");
  4049. this.move(upPart, xAdjust, yAdjustUp);
  4050. this.move(downPart, xAdjust + cMarginLeft, yAdjustDown);
  4051. }
  4052. }));
  4053. }
  4054. };
  4055. //src/layout/fish-bone-slave.js
  4056. /**
  4057. * @fileOverview
  4058. *
  4059. *
  4060. *
  4061. * @author: techird
  4062. * @copyright: Baidu FEX, 2014
  4063. */
  4064. _p[39] = {
  4065. value: function(require, exports, module) {
  4066. var kity = _p.r(17);
  4067. var Layout = _p.r(18);
  4068. Layout.register("fish-bone-slave", kity.createClass("FishBoneSlaveLayout", {
  4069. base: Layout,
  4070. doLayout: function(parent, children, round) {
  4071. var layout = this;
  4072. var abs = Math.abs;
  4073. var GOLD_CUT = 1 - .618;
  4074. var pBox = parent.getContentBox();
  4075. var vi = parent.getLayoutVectorIn();
  4076. parent.setLayoutVectorOut(vi);
  4077. var goldX = pBox.left + pBox.width * GOLD_CUT;
  4078. var pout = new kity.Point(goldX, vi.y > 0 ? pBox.bottom : pBox.top);
  4079. parent.setVertexOut(pout);
  4080. var child = children[0];
  4081. if (!child) return;
  4082. var cBox = child.getContentBox();
  4083. children.forEach(function(child, index) {
  4084. child.setLayoutTransform(new kity.Matrix());
  4085. child.setLayoutVectorIn(new kity.Vector(1, 0));
  4086. child.setVertexIn(new kity.Point(cBox.left, cBox.cy));
  4087. });
  4088. this.stack(children, "y");
  4089. this.align(children, "left");
  4090. var xAdjust = 0, yAdjust = 0;
  4091. xAdjust += pout.x;
  4092. if (parent.getLayoutVectorOut().y < 0) {
  4093. yAdjust -= this.getTreeBox(children).bottom;
  4094. yAdjust += parent.getContentBox().top;
  4095. yAdjust -= parent.getStyle("margin-top");
  4096. yAdjust -= child.getStyle("margin-bottom");
  4097. } else {
  4098. yAdjust += parent.getContentBox().bottom;
  4099. yAdjust += parent.getStyle("margin-bottom");
  4100. yAdjust += child.getStyle("margin-top");
  4101. }
  4102. this.move(children, xAdjust, yAdjust);
  4103. if (round == 2) {
  4104. children.forEach(function(child) {
  4105. var m = child.getLayoutTransform();
  4106. var cbox = child.getContentBox();
  4107. var pin = m.transformPoint(new kity.Point(cbox.left, 0));
  4108. layout.move([ child ], abs(pin.y - pout.y), 0);
  4109. });
  4110. }
  4111. }
  4112. }));
  4113. }
  4114. };
  4115. //src/layout/mind.js
  4116. _p[40] = {
  4117. value: function(require, exports, module) {
  4118. var kity = _p.r(17);
  4119. var Layout = _p.r(18);
  4120. var Minder = _p.r(19);
  4121. Layout.register("mind", kity.createClass({
  4122. base: Layout,
  4123. doLayout: function(node, children) {
  4124. var layout = this;
  4125. var half = Math.ceil(node.children.length / 2);
  4126. var right = [];
  4127. var left = [];
  4128. children.forEach(function(child) {
  4129. if (child.getIndex() < half) right.push(child); else left.push(child);
  4130. });
  4131. var leftLayout = Minder.getLayoutInstance("left");
  4132. var rightLayout = Minder.getLayoutInstance("right");
  4133. leftLayout.doLayout(node, left);
  4134. rightLayout.doLayout(node, right);
  4135. var box = node.getContentBox();
  4136. node.setVertexOut(new kity.Point(box.cx, box.cy));
  4137. node.setLayoutVectorOut(new kity.Vector(0, 0));
  4138. },
  4139. getOrderHint: function(node) {
  4140. var hint = [];
  4141. var box = node.getLayoutBox();
  4142. var offset = 5;
  4143. hint.push({
  4144. type: "up",
  4145. node: node,
  4146. area: new kity.Box({
  4147. x: box.x,
  4148. y: box.top - node.getStyle("margin-top") - offset,
  4149. width: box.width,
  4150. height: node.getStyle("margin-top")
  4151. }),
  4152. path: [ "M", box.x, box.top - offset, "L", box.right, box.top - offset ]
  4153. });
  4154. hint.push({
  4155. type: "down",
  4156. node: node,
  4157. area: new kity.Box({
  4158. x: box.x,
  4159. y: box.bottom + offset,
  4160. width: box.width,
  4161. height: node.getStyle("margin-bottom")
  4162. }),
  4163. path: [ "M", box.x, box.bottom + offset, "L", box.right, box.bottom + offset ]
  4164. });
  4165. return hint;
  4166. }
  4167. }));
  4168. }
  4169. };
  4170. //src/layout/tianpan.js
  4171. /**
  4172. * @fileOverview
  4173. *
  4174. * 天盘模板
  4175. *
  4176. * @author: along
  4177. * @copyright: bpd729@163.com, 2015
  4178. */
  4179. _p[41] = {
  4180. value: function(require, exports, module) {
  4181. var kity = _p.r(17);
  4182. var Layout = _p.r(18);
  4183. var Minder = _p.r(19);
  4184. Layout.register("tianpan", kity.createClass({
  4185. base: Layout,
  4186. doLayout: function(parent, children) {
  4187. if (children.length == 0) return;
  4188. var layout = this;
  4189. var pbox = parent.getContentBox();
  4190. var x, y, box;
  4191. var _theta = 5;
  4192. var _r = Math.max(pbox.width, 50);
  4193. children.forEach(function(child, index) {
  4194. child.setLayoutTransform(new kity.Matrix());
  4195. box = layout.getTreeBox(child);
  4196. _r = Math.max(Math.max(box.width, box.height), _r);
  4197. });
  4198. _r = _r / 1.5 / Math.PI;
  4199. children.forEach(function(child, index) {
  4200. x = _r * (Math.cos(_theta) + Math.sin(_theta) * _theta);
  4201. y = _r * (Math.sin(_theta) - Math.cos(_theta) * _theta);
  4202. _theta += .9 - index * .02;
  4203. child.setLayoutVectorIn(new kity.Vector(1, 0));
  4204. child.setVertexIn(new kity.Point(pbox.cx, pbox.cy));
  4205. child.setLayoutTransform(new kity.Matrix());
  4206. layout.move([ child ], x, y);
  4207. });
  4208. },
  4209. getOrderHint: function(node) {
  4210. var hint = [];
  4211. var box = node.getLayoutBox();
  4212. var offset = 5;
  4213. hint.push({
  4214. type: "up",
  4215. node: node,
  4216. area: {
  4217. x: box.x,
  4218. y: box.top - node.getStyle("margin-top") - offset,
  4219. width: box.width,
  4220. height: node.getStyle("margin-top")
  4221. },
  4222. path: [ "M", box.x, box.top - offset, "L", box.right, box.top - offset ]
  4223. });
  4224. hint.push({
  4225. type: "down",
  4226. node: node,
  4227. area: {
  4228. x: box.x,
  4229. y: box.bottom + offset,
  4230. width: box.width,
  4231. height: node.getStyle("margin-bottom")
  4232. },
  4233. path: [ "M", box.x, box.bottom + offset, "L", box.right, box.bottom + offset ]
  4234. });
  4235. return hint;
  4236. }
  4237. }));
  4238. }
  4239. };
  4240. //src/module/arrange.js
  4241. _p[42] = {
  4242. value: function(require, exports, module) {
  4243. var kity = _p.r(17);
  4244. var MinderNode = _p.r(21);
  4245. var Command = _p.r(9);
  4246. var Module = _p.r(20);
  4247. kity.extendClass(MinderNode, {
  4248. arrange: function(index) {
  4249. var parent = this.parent;
  4250. if (!parent) return;
  4251. var sibling = parent.children;
  4252. if (index < 0 || index >= sibling.length) return;
  4253. sibling.splice(this.getIndex(), 1);
  4254. sibling.splice(index, 0, this);
  4255. return this;
  4256. }
  4257. });
  4258. function asc(nodeA, nodeB) {
  4259. return nodeA.getIndex() - nodeB.getIndex();
  4260. }
  4261. function desc(nodeA, nodeB) {
  4262. return -asc(nodeA, nodeB);
  4263. }
  4264. function canArrange(km) {
  4265. var selected = km.getSelectedNode();
  4266. return selected && selected.parent && selected.parent.children.length > 1;
  4267. }
  4268. /**
  4269. * @command ArrangeUp
  4270. * @description 向上调整选中节点的位置
  4271. * @shortcut Alt + Up
  4272. * @state
  4273. * 0: 当前选中了具有相同父亲的节点
  4274. * -1: 其它情况
  4275. */
  4276. var ArrangeUpCommand = kity.createClass("ArrangeUpCommand", {
  4277. base: Command,
  4278. execute: function(km) {
  4279. var nodes = km.getSelectedNodes();
  4280. nodes.sort(asc);
  4281. var lastIndexes = nodes.map(function(node) {
  4282. return node.getIndex();
  4283. });
  4284. nodes.forEach(function(node, index) {
  4285. node.arrange(lastIndexes[index] - 1);
  4286. });
  4287. km.layout(300);
  4288. },
  4289. queryState: function(km) {
  4290. var selected = km.getSelectedNode();
  4291. return selected ? 0 : -1;
  4292. }
  4293. });
  4294. /**
  4295. * @command ArrangeDown
  4296. * @description 向下调整选中节点的位置
  4297. * @shortcut Alt + Down
  4298. * @state
  4299. * 0: 当前选中了具有相同父亲的节点
  4300. * -1: 其它情况
  4301. */
  4302. var ArrangeDownCommand = kity.createClass("ArrangeUpCommand", {
  4303. base: Command,
  4304. execute: function(km) {
  4305. var nodes = km.getSelectedNodes();
  4306. nodes.sort(desc);
  4307. var lastIndexes = nodes.map(function(node) {
  4308. return node.getIndex();
  4309. });
  4310. nodes.forEach(function(node, index) {
  4311. node.arrange(lastIndexes[index] + 1);
  4312. });
  4313. km.layout(300);
  4314. },
  4315. queryState: function(km) {
  4316. var selected = km.getSelectedNode();
  4317. return selected ? 0 : -1;
  4318. }
  4319. });
  4320. /**
  4321. * @command Arrange
  4322. * @description 调整选中节点的位置
  4323. * @param {number} index 调整后节点的新位置
  4324. * @state
  4325. * 0: 当前选中了具有相同父亲的节点
  4326. * -1: 其它情况
  4327. */
  4328. var ArrangeCommand = kity.createClass("ArrangeCommand", {
  4329. base: Command,
  4330. execute: function(km, index) {
  4331. var nodes = km.getSelectedNodes().slice();
  4332. if (!nodes.length) return;
  4333. var ancestor = MinderNode.getCommonAncestor(nodes);
  4334. if (ancestor != nodes[0].parent) return;
  4335. var indexed = nodes.map(function(node) {
  4336. return {
  4337. index: node.getIndex(),
  4338. node: node
  4339. };
  4340. });
  4341. var asc = Math.min.apply(Math, indexed.map(function(one) {
  4342. return one.index;
  4343. })) >= index;
  4344. indexed.sort(function(a, b) {
  4345. return asc ? b.index - a.index : a.index - b.index;
  4346. });
  4347. indexed.forEach(function(one) {
  4348. one.node.arrange(index);
  4349. });
  4350. km.layout(300);
  4351. },
  4352. queryState: function(km) {
  4353. var selected = km.getSelectedNode();
  4354. return selected ? 0 : -1;
  4355. }
  4356. });
  4357. Module.register("ArrangeModule", {
  4358. commands: {
  4359. arrangeup: ArrangeUpCommand,
  4360. arrangedown: ArrangeDownCommand,
  4361. arrange: ArrangeCommand
  4362. },
  4363. contextmenu: [ {
  4364. command: "arrangeup"
  4365. }, {
  4366. command: "arrangedown"
  4367. }, {
  4368. divider: true
  4369. } ],
  4370. commandShortcutKeys: {
  4371. arrangeup: "normal::alt+Up",
  4372. arrangedown: "normal::alt+Down"
  4373. }
  4374. });
  4375. }
  4376. };
  4377. //src/module/basestyle.js
  4378. _p[43] = {
  4379. value: function(require, exports, module) {
  4380. var kity = _p.r(17);
  4381. var utils = _p.r(33);
  4382. var Minder = _p.r(19);
  4383. var MinderNode = _p.r(21);
  4384. var Command = _p.r(9);
  4385. var Module = _p.r(20);
  4386. var TextRenderer = _p.r(61);
  4387. Module.register("basestylemodule", function() {
  4388. var km = this;
  4389. function getNodeDataOrStyle(node, name) {
  4390. return node.getData(name) || node.getStyle(name);
  4391. }
  4392. TextRenderer.registerStyleHook(function(node, textGroup) {
  4393. var fontWeight = getNodeDataOrStyle(node, "font-weight");
  4394. var fontStyle = getNodeDataOrStyle(node, "font-style");
  4395. var styleHash = [ fontWeight, fontStyle ].join("/");
  4396. textGroup.eachItem(function(index, item) {
  4397. item.setFont({
  4398. weight: fontWeight,
  4399. style: fontStyle
  4400. });
  4401. });
  4402. });
  4403. return {
  4404. commands: {
  4405. /**
  4406. * @command Bold
  4407. * @description 加粗选中的节点
  4408. * @shortcut Ctrl + B
  4409. * @state
  4410. * 0: 当前有选中的节点
  4411. * -1: 当前没有选中的节点
  4412. * 1: 当前已选中的节点已加粗
  4413. */
  4414. bold: kity.createClass("boldCommand", {
  4415. base: Command,
  4416. execute: function(km) {
  4417. var nodes = km.getSelectedNodes();
  4418. if (this.queryState("bold") == 1) {
  4419. nodes.forEach(function(n) {
  4420. n.setData("font-weight").render();
  4421. });
  4422. } else {
  4423. nodes.forEach(function(n) {
  4424. n.setData("font-weight", "bold").render();
  4425. });
  4426. }
  4427. km.layout();
  4428. },
  4429. queryState: function() {
  4430. var nodes = km.getSelectedNodes(), result = 0;
  4431. if (nodes.length === 0) {
  4432. return -1;
  4433. }
  4434. nodes.forEach(function(n) {
  4435. if (n && n.getData("font-weight")) {
  4436. result = 1;
  4437. return false;
  4438. }
  4439. });
  4440. return result;
  4441. }
  4442. }),
  4443. /**
  4444. * @command Italic
  4445. * @description 加斜选中的节点
  4446. * @shortcut Ctrl + I
  4447. * @state
  4448. * 0: 当前有选中的节点
  4449. * -1: 当前没有选中的节点
  4450. * 1: 当前已选中的节点已加斜
  4451. */
  4452. italic: kity.createClass("italicCommand", {
  4453. base: Command,
  4454. execute: function(km) {
  4455. var nodes = km.getSelectedNodes();
  4456. if (this.queryState("italic") == 1) {
  4457. nodes.forEach(function(n) {
  4458. n.setData("font-style").render();
  4459. });
  4460. } else {
  4461. nodes.forEach(function(n) {
  4462. n.setData("font-style", "italic").render();
  4463. });
  4464. }
  4465. km.layout();
  4466. },
  4467. queryState: function() {
  4468. var nodes = km.getSelectedNodes(), result = 0;
  4469. if (nodes.length === 0) {
  4470. return -1;
  4471. }
  4472. nodes.forEach(function(n) {
  4473. if (n && n.getData("font-style")) {
  4474. result = 1;
  4475. return false;
  4476. }
  4477. });
  4478. return result;
  4479. }
  4480. })
  4481. },
  4482. commandShortcutKeys: {
  4483. bold: "ctrl+b",
  4484. //bold
  4485. italic: "ctrl+i"
  4486. }
  4487. };
  4488. });
  4489. }
  4490. };
  4491. //src/module/clipboard.js
  4492. _p[44] = {
  4493. value: function(require, exports, module) {
  4494. var kity = _p.r(17);
  4495. var utils = _p.r(33);
  4496. var MinderNode = _p.r(21);
  4497. var Command = _p.r(9);
  4498. var Module = _p.r(20);
  4499. Module.register("ClipboardModule", function() {
  4500. var km = this, _clipboardNodes = [], _selectedNodes = [];
  4501. function appendChildNode(parent, child) {
  4502. _selectedNodes.push(child);
  4503. km.appendNode(child, parent);
  4504. child.render();
  4505. child.setLayoutOffset(null);
  4506. var children = child.children.map(function(node) {
  4507. return node.clone();
  4508. });
  4509. /*
  4510. * fixed bug: Modified on 2015.08.05
  4511. * 原因:粘贴递归 append 时没有清空原来父节点的子节点,而父节点被复制的时候,是连同子节点一起复制过来的
  4512. * 解决办法:增加了下面这一行代码
  4513. * by: @zhangbobell zhangbobell@163.com
  4514. */
  4515. child.clearChildren();
  4516. for (var i = 0, ci; ci = children[i]; i++) {
  4517. appendChildNode(child, ci);
  4518. }
  4519. }
  4520. function sendToClipboard(nodes) {
  4521. if (!nodes.length) return;
  4522. nodes.sort(function(a, b) {
  4523. return a.getIndex() - b.getIndex();
  4524. });
  4525. _clipboardNodes = nodes.map(function(node) {
  4526. return node.clone();
  4527. });
  4528. }
  4529. /**
  4530. * @command Copy
  4531. * @description 复制当前选中的节点
  4532. * @shortcut Ctrl + C
  4533. * @state
  4534. * 0: 当前有选中的节点
  4535. * -1: 当前没有选中的节点
  4536. */
  4537. var CopyCommand = kity.createClass("CopyCommand", {
  4538. base: Command,
  4539. execute: function(km) {
  4540. sendToClipboard(km.getSelectedAncestors(true));
  4541. this.setContentChanged(false);
  4542. }
  4543. });
  4544. /**
  4545. * @command Cut
  4546. * @description 剪切当前选中的节点
  4547. * @shortcut Ctrl + X
  4548. * @state
  4549. * 0: 当前有选中的节点
  4550. * -1: 当前没有选中的节点
  4551. */
  4552. var CutCommand = kity.createClass("CutCommand", {
  4553. base: Command,
  4554. execute: function(km) {
  4555. var ancestors = km.getSelectedAncestors();
  4556. if (ancestors.length === 0) return;
  4557. sendToClipboard(ancestors);
  4558. km.select(MinderNode.getCommonAncestor(ancestors), true);
  4559. ancestors.slice().forEach(function(node) {
  4560. km.removeNode(node);
  4561. });
  4562. km.layout(300);
  4563. }
  4564. });
  4565. /**
  4566. * @command Paste
  4567. * @description 粘贴已复制的节点到每一个当前选中的节点上
  4568. * @shortcut Ctrl + V
  4569. * @state
  4570. * 0: 当前有选中的节点
  4571. * -1: 当前没有选中的节点
  4572. */
  4573. var PasteCommand = kity.createClass("PasteCommand", {
  4574. base: Command,
  4575. execute: function(km) {
  4576. if (_clipboardNodes.length) {
  4577. var nodes = km.getSelectedNodes();
  4578. if (!nodes.length) return;
  4579. for (var i = 0, ni; ni = _clipboardNodes[i]; i++) {
  4580. for (var j = 0, node; node = nodes[j]; j++) {
  4581. appendChildNode(node, ni.clone());
  4582. }
  4583. }
  4584. km.select(_selectedNodes, true);
  4585. _selectedNodes = [];
  4586. km.layout(300);
  4587. }
  4588. },
  4589. queryState: function(km) {
  4590. return km.getSelectedNode() ? 0 : -1;
  4591. }
  4592. });
  4593. /**
  4594. * @Desc: 若支持原生clipboadr事件则基于原生扩展,否则使用km的基础事件只处理节点的粘贴复制
  4595. * @Editor: Naixor
  4596. * @Date: 2015.9.20
  4597. */
  4598. if (km.supportClipboardEvent && !kity.Browser.gecko) {
  4599. var Copy = function(e) {
  4600. this.fire("beforeCopy", e);
  4601. };
  4602. var Cut = function(e) {
  4603. this.fire("beforeCut", e);
  4604. };
  4605. var Paste = function(e) {
  4606. this.fire("beforePaste", e);
  4607. };
  4608. return {
  4609. commands: {
  4610. copy: CopyCommand,
  4611. cut: CutCommand,
  4612. paste: PasteCommand
  4613. },
  4614. clipBoardEvents: {
  4615. copy: Copy.bind(km),
  4616. cut: Cut.bind(km),
  4617. paste: Paste.bind(km)
  4618. },
  4619. sendToClipboard: sendToClipboard
  4620. };
  4621. } else {
  4622. return {
  4623. commands: {
  4624. copy: CopyCommand,
  4625. cut: CutCommand,
  4626. paste: PasteCommand
  4627. },
  4628. commandShortcutKeys: {
  4629. copy: "normal::ctrl+c|",
  4630. cut: "normal::ctrl+x",
  4631. paste: "normal::ctrl+v"
  4632. },
  4633. sendToClipboard: sendToClipboard
  4634. };
  4635. }
  4636. });
  4637. }
  4638. };
  4639. //src/module/dragtree.js
  4640. _p[45] = {
  4641. value: function(require, exports, module) {
  4642. var kity = _p.r(17);
  4643. var utils = _p.r(33);
  4644. var MinderNode = _p.r(21);
  4645. var Command = _p.r(9);
  4646. var Module = _p.r(20);
  4647. // 矩形的变形动画定义
  4648. var MoveToParentCommand = kity.createClass("MoveToParentCommand", {
  4649. base: Command,
  4650. execute: function(minder, nodes, parent) {
  4651. var node;
  4652. for (var i = 0; i < nodes.length; i++) {
  4653. node = nodes[i];
  4654. if (node.parent) {
  4655. node.parent.removeChild(node);
  4656. parent.appendChild(node);
  4657. node.render();
  4658. }
  4659. }
  4660. parent.expand();
  4661. minder.select(nodes, true);
  4662. }
  4663. });
  4664. var DropHinter = kity.createClass("DropHinter", {
  4665. base: kity.Group,
  4666. constructor: function() {
  4667. this.callBase();
  4668. this.rect = new kity.Rect();
  4669. this.addShape(this.rect);
  4670. },
  4671. render: function(target) {
  4672. this.setVisible(!!target);
  4673. if (target) {
  4674. this.rect.setBox(target.getLayoutBox()).setRadius(target.getStyle("radius") || 0).stroke(target.getStyle("drop-hint-color") || "yellow", target.getStyle("drop-hint-width") || 2);
  4675. this.bringTop();
  4676. }
  4677. }
  4678. });
  4679. var OrderHinter = kity.createClass("OrderHinter", {
  4680. base: kity.Group,
  4681. constructor: function() {
  4682. this.callBase();
  4683. this.area = new kity.Rect();
  4684. this.path = new kity.Path();
  4685. this.addShapes([ this.area, this.path ]);
  4686. },
  4687. render: function(hint) {
  4688. this.setVisible(!!hint);
  4689. if (hint) {
  4690. this.area.setBox(hint.area);
  4691. this.area.fill(hint.node.getStyle("order-hint-area-color") || "rgba(0, 255, 0, .5)");
  4692. this.path.setPathData(hint.path);
  4693. this.path.stroke(hint.node.getStyle("order-hint-path-color") || "#0f0", hint.node.getStyle("order-hint-path-width") || 1);
  4694. }
  4695. }
  4696. });
  4697. // 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括:
  4698. // 1. 从节点列表计算出拖动部分
  4699. // 2. 计算可以 drop 的节点,产生 drop 交互提示
  4700. var TreeDragger = kity.createClass("TreeDragger", {
  4701. constructor: function(minder) {
  4702. this._minder = minder;
  4703. this._dropHinter = new DropHinter();
  4704. this._orderHinter = new OrderHinter();
  4705. minder.getRenderContainer().addShapes([ this._dropHinter, this._orderHinter ]);
  4706. },
  4707. dragStart: function(position) {
  4708. // 只记录开始位置,不马上开启拖放模式
  4709. // 这个位置同时是拖放范围收缩时的焦点位置(中心)
  4710. this._startPosition = position;
  4711. },
  4712. dragMove: function(position) {
  4713. // 启动拖放模式需要最小的移动距离
  4714. var DRAG_MOVE_THRESHOLD = 10;
  4715. if (!this._startPosition) return;
  4716. var movement = kity.Vector.fromPoints(this._dragPosition || this._startPosition, position);
  4717. var minder = this._minder;
  4718. this._dragPosition = position;
  4719. if (!this._dragMode) {
  4720. // 判断拖放模式是否该启动
  4721. if (kity.Vector.fromPoints(this._dragPosition, this._startPosition).length() < DRAG_MOVE_THRESHOLD) {
  4722. return;
  4723. }
  4724. if (!this._enterDragMode()) {
  4725. return;
  4726. }
  4727. }
  4728. for (var i = 0; i < this._dragSources.length; i++) {
  4729. this._dragSources[i].setLayoutOffset(this._dragSources[i].getLayoutOffset().offset(movement));
  4730. minder.applyLayoutResult(this._dragSources[i]);
  4731. }
  4732. if (!this._dropTest()) {
  4733. this._orderTest();
  4734. } else {
  4735. this._renderOrderHint(this._orderSucceedHint = null);
  4736. }
  4737. },
  4738. dragEnd: function() {
  4739. this._startPosition = null;
  4740. this._dragPosition = null;
  4741. if (!this._dragMode) {
  4742. return;
  4743. }
  4744. this._fadeDragSources(1);
  4745. if (this._dropSucceedTarget) {
  4746. this._dragSources.forEach(function(source) {
  4747. source.setLayoutOffset(null);
  4748. });
  4749. this._minder.layout(-1);
  4750. this._minder.execCommand("movetoparent", this._dragSources, this._dropSucceedTarget);
  4751. } else if (this._orderSucceedHint) {
  4752. var hint = this._orderSucceedHint;
  4753. var index = hint.node.getIndex();
  4754. var sourceIndexes = this._dragSources.map(function(source) {
  4755. // 顺便干掉布局偏移
  4756. source.setLayoutOffset(null);
  4757. return source.getIndex();
  4758. });
  4759. var maxIndex = Math.max.apply(Math, sourceIndexes);
  4760. var minIndex = Math.min.apply(Math, sourceIndexes);
  4761. if (index < minIndex && hint.type == "down") index++;
  4762. if (index > maxIndex && hint.type == "up") index--;
  4763. hint.node.setLayoutOffset(null);
  4764. this._minder.execCommand("arrange", index);
  4765. this._renderOrderHint(null);
  4766. } else {
  4767. this._minder.fire("savescene");
  4768. }
  4769. this._minder.layout(300);
  4770. this._leaveDragMode();
  4771. this._minder.fire("contentchange");
  4772. },
  4773. // 进入拖放模式:
  4774. // 1. 计算拖放源和允许的拖放目标
  4775. // 2. 标记已启动
  4776. _enterDragMode: function() {
  4777. this._calcDragSources();
  4778. if (!this._dragSources.length) {
  4779. this._startPosition = null;
  4780. return false;
  4781. }
  4782. this._fadeDragSources(.5);
  4783. this._calcDropTargets();
  4784. this._calcOrderHints();
  4785. this._dragMode = true;
  4786. this._minder.setStatus("dragtree");
  4787. return true;
  4788. },
  4789. // 从选中的节点计算拖放源
  4790. // 并不是所有选中的节点都作为拖放源,如果选中节点中存在 A 和 B,
  4791. // 并且 A 是 B 的祖先,则 B 不作为拖放源
  4792. //
  4793. // 计算过程:
  4794. // 1. 将节点按照树高排序,排序后只可能是前面节点是后面节点的祖先
  4795. // 2. 从后往前枚举排序的结果,如果发现枚举目标之前存在其祖先,
  4796. // 则排除枚举目标作为拖放源,否则加入拖放源
  4797. _calcDragSources: function() {
  4798. this._dragSources = this._minder.getSelectedAncestors();
  4799. },
  4800. _fadeDragSources: function(opacity) {
  4801. var minder = this._minder;
  4802. this._dragSources.forEach(function(source) {
  4803. source.getRenderContainer().setOpacity(opacity, 200);
  4804. source.traverse(function(node) {
  4805. if (opacity < 1) {
  4806. minder.detachNode(node);
  4807. } else {
  4808. minder.attachNode(node);
  4809. }
  4810. }, true);
  4811. });
  4812. },
  4813. // 计算拖放目标可以释放的节点列表(释放意味着成为其子树),存在这条限制规则:
  4814. // - 不能拖放到拖放目标的子树上(允许拖放到自身,因为多选的情况下可以把其它节点加入)
  4815. //
  4816. // 1. 加入当前节点(初始为根节点)到允许列表
  4817. // 2. 对于当前节点的每一个子节点:
  4818. // (1) 如果是拖放目标的其中一个节点,忽略(整棵子树被剪枝)
  4819. // (2) 如果不是拖放目标之一,以当前子节点为当前节点,回到 1 计算
  4820. // 3. 返回允许列表
  4821. //
  4822. _calcDropTargets: function() {
  4823. function findAvailableParents(nodes, root) {
  4824. var availables = [], i;
  4825. availables.push(root);
  4826. root.getChildren().forEach(function(test) {
  4827. for (i = 0; i < nodes.length; i++) {
  4828. if (nodes[i] == test) return;
  4829. }
  4830. availables = availables.concat(findAvailableParents(nodes, test));
  4831. });
  4832. return availables;
  4833. }
  4834. this._dropTargets = findAvailableParents(this._dragSources, this._minder.getRoot());
  4835. this._dropTargetBoxes = this._dropTargets.map(function(source) {
  4836. return source.getLayoutBox();
  4837. });
  4838. },
  4839. _calcOrderHints: function() {
  4840. var sources = this._dragSources;
  4841. var ancestor = MinderNode.getCommonAncestor(sources);
  4842. // 只有一个元素选中,公共祖先是其父
  4843. if (ancestor == sources[0]) ancestor = sources[0].parent;
  4844. if (sources.length === 0 || ancestor != sources[0].parent) {
  4845. this._orderHints = [];
  4846. return;
  4847. }
  4848. var siblings = ancestor.children;
  4849. this._orderHints = siblings.reduce(function(hint, sibling) {
  4850. if (sources.indexOf(sibling) == -1) {
  4851. hint = hint.concat(sibling.getOrderHint());
  4852. }
  4853. return hint;
  4854. }, []);
  4855. },
  4856. _leaveDragMode: function() {
  4857. this._dragMode = false;
  4858. this._dropSucceedTarget = null;
  4859. this._orderSucceedHint = null;
  4860. this._renderDropHint(null);
  4861. this._renderOrderHint(null);
  4862. this._minder.rollbackStatus();
  4863. },
  4864. _drawForDragMode: function() {
  4865. this._text.setContent(this._dragSources.length + " items");
  4866. this._text.setPosition(this._startPosition.x, this._startPosition.y + 5);
  4867. this._minder.getRenderContainer().addShape(this);
  4868. },
  4869. /**
  4870. * 通过 judge 函数判断 targetBox 和 sourceBox 的位置交叉关系
  4871. * @param targets -- 目标节点
  4872. * @param targetBoxMapper -- 目标节点与对应 Box 的映射关系
  4873. * @param judge -- 判断函数
  4874. * @returns {*}
  4875. * @private
  4876. */
  4877. _boxTest: function(targets, targetBoxMapper, judge) {
  4878. var sourceBoxes = this._dragSources.map(function(source) {
  4879. return source.getLayoutBox();
  4880. });
  4881. var i, j, target, sourceBox, targetBox;
  4882. judge = judge || function(intersectBox, sourceBox, targetBox) {
  4883. return intersectBox && !intersectBox.isEmpty();
  4884. };
  4885. for (i = 0; i < targets.length; i++) {
  4886. target = targets[i];
  4887. targetBox = targetBoxMapper.call(this, target, i);
  4888. for (j = 0; j < sourceBoxes.length; j++) {
  4889. sourceBox = sourceBoxes[j];
  4890. var intersectBox = sourceBox.intersect(targetBox);
  4891. if (judge(intersectBox, sourceBox, targetBox)) {
  4892. return target;
  4893. }
  4894. }
  4895. }
  4896. return null;
  4897. },
  4898. _dropTest: function() {
  4899. this._dropSucceedTarget = this._boxTest(this._dropTargets, function(target, i) {
  4900. return this._dropTargetBoxes[i];
  4901. }, function(intersectBox, sourceBox, targetBox) {
  4902. function area(box) {
  4903. return box.width * box.height;
  4904. }
  4905. if (!intersectBox) return false;
  4906. /*
  4907. * Added by zhangbobell, 2015.9.8
  4908. *
  4909. * 增加了下面一行判断,修复了循环比较中 targetBox 为折叠节点时,intersetBox 面积为 0,
  4910. * 而 targetBox 的 width 和 height 均为 0
  4911. * 此时造成了满足以下的第二个条件而返回 true
  4912. * */
  4913. if (!area(intersectBox)) return false;
  4914. // 面积判断,交叉面积大于其中的一半
  4915. if (area(intersectBox) > .5 * Math.min(area(sourceBox), area(targetBox))) return true;
  4916. // 有一个边完全重合的情况,也认为两个是交叉的
  4917. if (intersectBox.width + 1 >= Math.min(sourceBox.width, targetBox.width)) return true;
  4918. if (intersectBox.height + 1 >= Math.min(sourceBox.height, targetBox.height)) return true;
  4919. return false;
  4920. });
  4921. this._renderDropHint(this._dropSucceedTarget);
  4922. return !!this._dropSucceedTarget;
  4923. },
  4924. _orderTest: function() {
  4925. this._orderSucceedHint = this._boxTest(this._orderHints, function(hint) {
  4926. return hint.area;
  4927. });
  4928. this._renderOrderHint(this._orderSucceedHint);
  4929. return !!this._orderSucceedHint;
  4930. },
  4931. _renderDropHint: function(target) {
  4932. this._dropHinter.render(target);
  4933. },
  4934. _renderOrderHint: function(hint) {
  4935. this._orderHinter.render(hint);
  4936. },
  4937. preventDragMove: function() {
  4938. this._startPosition = null;
  4939. }
  4940. });
  4941. Module.register("DragTree", function() {
  4942. var dragger;
  4943. return {
  4944. init: function() {
  4945. dragger = new TreeDragger(this);
  4946. window.addEventListener("mouseup", function() {
  4947. dragger.dragEnd();
  4948. });
  4949. },
  4950. events: {
  4951. "normal.mousedown inputready.mousedown": function(e) {
  4952. // 单选中根节点也不触发拖拽
  4953. if (e.originEvent.button) return;
  4954. if (e.getTargetNode() && e.getTargetNode() != this.getRoot()) {
  4955. dragger.dragStart(e.getPosition());
  4956. }
  4957. },
  4958. "normal.mousemove dragtree.mousemove": function(e) {
  4959. dragger.dragMove(e.getPosition());
  4960. },
  4961. "normal.mouseup dragtree.beforemouseup": function(e) {
  4962. dragger.dragEnd();
  4963. //e.stopPropagation();
  4964. e.preventDefault();
  4965. },
  4966. statuschange: function(e) {
  4967. if (e.lastStatus == "textedit" && e.currentStatus == "normal") {
  4968. dragger.preventDragMove();
  4969. }
  4970. }
  4971. },
  4972. commands: {
  4973. movetoparent: MoveToParentCommand
  4974. }
  4975. };
  4976. });
  4977. }
  4978. };
  4979. //src/module/expand.js
  4980. _p[46] = {
  4981. value: function(require, exports, module) {
  4982. var kity = _p.r(17);
  4983. var utils = _p.r(33);
  4984. var keymap = _p.r(15);
  4985. var MinderNode = _p.r(21);
  4986. var Command = _p.r(9);
  4987. var Module = _p.r(20);
  4988. var Renderer = _p.r(27);
  4989. Module.register("Expand", function() {
  4990. var minder = this;
  4991. var EXPAND_STATE_DATA = "expandState", STATE_EXPAND = "expand", STATE_COLLAPSE = "collapse";
  4992. // 将展开的操作和状态读取接口拓展到 MinderNode 上
  4993. kity.extendClass(MinderNode, {
  4994. /**
  4995. * 展开节点
  4996. * @param {Policy} policy 展开的策略,默认为 KEEP_STATE
  4997. */
  4998. expand: function() {
  4999. this.setData(EXPAND_STATE_DATA, STATE_EXPAND);
  5000. return this;
  5001. },
  5002. /**
  5003. * 收起节点
  5004. */
  5005. collapse: function() {
  5006. this.setData(EXPAND_STATE_DATA, STATE_COLLAPSE);
  5007. return this;
  5008. },
  5009. /**
  5010. * 判断节点当前的状态是否为展开
  5011. */
  5012. isExpanded: function() {
  5013. var expanded = this.getData(EXPAND_STATE_DATA) !== STATE_COLLAPSE;
  5014. return expanded && (this.isRoot() || this.parent.isExpanded());
  5015. },
  5016. /**
  5017. * 判断节点当前的状态是否为收起
  5018. */
  5019. isCollapsed: function() {
  5020. return !this.isExpanded();
  5021. }
  5022. });
  5023. /**
  5024. * @command Expand
  5025. * @description 展开当前选中的节点,保证其可见
  5026. * @param {bool} justParents 是否只展开到父亲
  5027. * * `false` - (默认)保证选中的节点以及其子树可见
  5028. * * `true` - 只保证选中的节点可见,不展开其子树
  5029. * @state
  5030. * 0: 当前有选中的节点
  5031. * -1: 当前没有选中的节点
  5032. */
  5033. var ExpandCommand = kity.createClass("ExpandCommand", {
  5034. base: Command,
  5035. execute: function(km, justParents) {
  5036. var node = km.getSelectedNode();
  5037. if (!node) return;
  5038. if (justParents) {
  5039. node = node.parent;
  5040. }
  5041. while (node.parent) {
  5042. node.expand();
  5043. node = node.parent;
  5044. }
  5045. node.renderTree();
  5046. km.layout(100);
  5047. },
  5048. queryState: function(km) {
  5049. var node = km.getSelectedNode();
  5050. return node && !node.isRoot() && !node.isExpanded() ? 0 : -1;
  5051. }
  5052. });
  5053. /**
  5054. * @command ExpandToLevel
  5055. * @description 展开脑图到指定的层级
  5056. * @param {number} level 指定展开到的层级,最少值为 1。
  5057. * @state
  5058. * 0: 一直可用
  5059. */
  5060. var ExpandToLevelCommand = kity.createClass("ExpandToLevelCommand", {
  5061. base: Command,
  5062. execute: function(km, level) {
  5063. km.getRoot().traverse(function(node) {
  5064. if (node.getLevel() < level) node.expand();
  5065. if (node.getLevel() == level && !node.isLeaf()) node.collapse();
  5066. });
  5067. km.refresh(100);
  5068. },
  5069. enableReadOnly: true
  5070. });
  5071. /**
  5072. * @command Collapse
  5073. * @description 收起当前节点的子树
  5074. * @state
  5075. * 0: 当前有选中的节点
  5076. * -1: 当前没有选中的节点
  5077. */
  5078. var CollapseCommand = kity.createClass("CollapseCommand", {
  5079. base: Command,
  5080. execute: function(km) {
  5081. var node = km.getSelectedNode();
  5082. if (!node) return;
  5083. node.collapse();
  5084. node.renderTree();
  5085. km.layout();
  5086. },
  5087. queryState: function(km) {
  5088. var node = km.getSelectedNode();
  5089. return node && !node.isRoot() && node.isExpanded() ? 0 : -1;
  5090. }
  5091. });
  5092. var Expander = kity.createClass("Expander", {
  5093. base: kity.Group,
  5094. constructor: function(node) {
  5095. this.callBase();
  5096. this.radius = 6;
  5097. this.outline = new kity.Circle(this.radius).stroke("gray").fill("white");
  5098. this.sign = new kity.Path().stroke("gray");
  5099. this.addShapes([ this.outline, this.sign ]);
  5100. this.initEvent(node);
  5101. this.setId(utils.uuid("node_expander"));
  5102. this.setStyle("cursor", "pointer");
  5103. },
  5104. initEvent: function(node) {
  5105. this.on("mousedown", function(e) {
  5106. minder.select([ node ], true);
  5107. if (node.isExpanded()) {
  5108. node.collapse();
  5109. } else {
  5110. node.expand();
  5111. }
  5112. node.renderTree().getMinder().layout(100);
  5113. node.getMinder().fire("contentchange");
  5114. e.stopPropagation();
  5115. e.preventDefault();
  5116. });
  5117. this.on("dblclick click mouseup", function(e) {
  5118. e.stopPropagation();
  5119. e.preventDefault();
  5120. });
  5121. },
  5122. setState: function(state) {
  5123. if (state == "hide") {
  5124. this.setVisible(false);
  5125. return;
  5126. }
  5127. this.setVisible(true);
  5128. var pathData = [ "M", 1.5 - this.radius, 0, "L", this.radius - 1.5, 0 ];
  5129. if (state == STATE_COLLAPSE) {
  5130. pathData.push([ "M", 0, 1.5 - this.radius, "L", 0, this.radius - 1.5 ]);
  5131. }
  5132. this.sign.setPathData(pathData);
  5133. }
  5134. });
  5135. var ExpanderRenderer = kity.createClass("ExpanderRenderer", {
  5136. base: Renderer,
  5137. create: function(node) {
  5138. if (node.isRoot()) return;
  5139. this.expander = new Expander(node);
  5140. node.getRenderContainer().prependShape(this.expander);
  5141. node.expanderRenderer = this;
  5142. this.node = node;
  5143. return this.expander;
  5144. },
  5145. shouldRender: function(node) {
  5146. return !node.isRoot();
  5147. },
  5148. update: function(expander, node, box) {
  5149. if (!node.parent) return;
  5150. var visible = node.parent.isExpanded();
  5151. expander.setState(visible && node.children.length ? node.getData(EXPAND_STATE_DATA) : "hide");
  5152. var vector = node.getLayoutVectorIn().normalize(expander.radius + node.getStyle("stroke-width"));
  5153. var position = node.getVertexIn().offset(vector.reverse());
  5154. this.expander.setTranslate(position);
  5155. }
  5156. });
  5157. return {
  5158. commands: {
  5159. expand: ExpandCommand,
  5160. expandtolevel: ExpandToLevelCommand,
  5161. collapse: CollapseCommand
  5162. },
  5163. events: {
  5164. layoutapply: function(e) {
  5165. var r = e.node.getRenderer("ExpanderRenderer");
  5166. if (r.getRenderShape()) {
  5167. r.update(r.getRenderShape(), e.node);
  5168. }
  5169. },
  5170. beforerender: function(e) {
  5171. var node = e.node;
  5172. var visible = !node.parent || node.parent.isExpanded();
  5173. var minder = this;
  5174. node.getRenderContainer().setVisible(visible);
  5175. if (!visible) e.stopPropagation();
  5176. },
  5177. "normal.keydown": function(e) {
  5178. if (this.getStatus() == "textedit") return;
  5179. if (e.originEvent.keyCode == keymap["/"]) {
  5180. var node = this.getSelectedNode();
  5181. if (!node || node == this.getRoot()) return;
  5182. var expanded = node.isExpanded();
  5183. this.getSelectedNodes().forEach(function(node) {
  5184. if (expanded) node.collapse(); else node.expand();
  5185. node.renderTree();
  5186. });
  5187. this.layout(100);
  5188. this.fire("contentchange");
  5189. e.preventDefault();
  5190. e.stopPropagationImmediately();
  5191. }
  5192. if (e.isShortcutKey("Alt+`")) {
  5193. this.execCommand("expandtolevel", 9999);
  5194. }
  5195. for (var i = 1; i < 6; i++) {
  5196. if (e.isShortcutKey("Alt+" + i)) {
  5197. this.execCommand("expandtolevel", i);
  5198. }
  5199. }
  5200. }
  5201. },
  5202. renderers: {
  5203. outside: ExpanderRenderer
  5204. },
  5205. contextmenu: [ {
  5206. command: "expandtoleaf",
  5207. query: function() {
  5208. return !minder.getSelectedNode();
  5209. },
  5210. fn: function(minder) {
  5211. minder.execCommand("expandtolevel", 9999);
  5212. }
  5213. }, {
  5214. command: "expandtolevel1",
  5215. query: function() {
  5216. return !minder.getSelectedNode();
  5217. },
  5218. fn: function(minder) {
  5219. minder.execCommand("expandtolevel", 1);
  5220. }
  5221. }, {
  5222. command: "expandtolevel2",
  5223. query: function() {
  5224. return !minder.getSelectedNode();
  5225. },
  5226. fn: function(minder) {
  5227. minder.execCommand("expandtolevel", 2);
  5228. }
  5229. }, {
  5230. command: "expandtolevel3",
  5231. query: function() {
  5232. return !minder.getSelectedNode();
  5233. },
  5234. fn: function(minder) {
  5235. minder.execCommand("expandtolevel", 3);
  5236. }
  5237. }, {
  5238. divider: true
  5239. } ]
  5240. };
  5241. });
  5242. }
  5243. };
  5244. //src/module/font.js
  5245. _p[47] = {
  5246. value: function(require, exports, module) {
  5247. var kity = _p.r(17);
  5248. var utils = _p.r(33);
  5249. var Minder = _p.r(19);
  5250. var MinderNode = _p.r(21);
  5251. var Command = _p.r(9);
  5252. var Module = _p.r(20);
  5253. var TextRenderer = _p.r(61);
  5254. function getNodeDataOrStyle(node, name) {
  5255. return node.getData(name) || node.getStyle(name);
  5256. }
  5257. TextRenderer.registerStyleHook(function(node, textGroup) {
  5258. var dataColor = node.getData("color");
  5259. var selectedColor = node.getStyle("selected-color");
  5260. var styleColor = node.getStyle("color");
  5261. var foreColor = dataColor || (node.isSelected() && selectedColor ? selectedColor : styleColor);
  5262. var fontFamily = getNodeDataOrStyle(node, "font-family");
  5263. var fontSize = getNodeDataOrStyle(node, "font-size");
  5264. textGroup.fill(foreColor);
  5265. textGroup.eachItem(function(index, item) {
  5266. item.setFont({
  5267. family: fontFamily,
  5268. size: fontSize
  5269. });
  5270. });
  5271. });
  5272. Module.register("fontmodule", {
  5273. commands: {
  5274. /**
  5275. * @command ForeColor
  5276. * @description 设置选中节点的字体颜色
  5277. * @param {string} color 表示颜色的字符串
  5278. * @state
  5279. * 0: 当前有选中的节点
  5280. * -1: 当前没有选中的节点
  5281. * @return 如果只有一个节点选中,返回已选中节点的字体颜色;否则返回 'mixed'。
  5282. */
  5283. forecolor: kity.createClass("fontcolorCommand", {
  5284. base: Command,
  5285. execute: function(km, color) {
  5286. var nodes = km.getSelectedNodes();
  5287. nodes.forEach(function(n) {
  5288. n.setData("color", color);
  5289. n.render();
  5290. });
  5291. },
  5292. queryState: function(km) {
  5293. return km.getSelectedNodes().length === 0 ? -1 : 0;
  5294. },
  5295. queryValue: function(km) {
  5296. if (km.getSelectedNodes().length == 1) {
  5297. return km.getSelectedNodes()[0].getData("color");
  5298. }
  5299. return "mixed";
  5300. }
  5301. }),
  5302. /**
  5303. * @command Background
  5304. * @description 设置选中节点的背景颜色
  5305. * @param {string} color 表示颜色的字符串
  5306. * @state
  5307. * 0: 当前有选中的节点
  5308. * -1: 当前没有选中的节点
  5309. * @return 如果只有一个节点选中,返回已选中节点的背景颜色;否则返回 'mixed'。
  5310. */
  5311. background: kity.createClass("backgroudCommand", {
  5312. base: Command,
  5313. execute: function(km, color) {
  5314. var nodes = km.getSelectedNodes();
  5315. nodes.forEach(function(n) {
  5316. n.setData("background", color);
  5317. n.render();
  5318. });
  5319. },
  5320. queryState: function(km) {
  5321. return km.getSelectedNodes().length === 0 ? -1 : 0;
  5322. },
  5323. queryValue: function(km) {
  5324. if (km.getSelectedNodes().length == 1) {
  5325. return km.getSelectedNodes()[0].getData("background");
  5326. }
  5327. return "mixed";
  5328. }
  5329. }),
  5330. /**
  5331. * @command FontFamily
  5332. * @description 设置选中节点的字体
  5333. * @param {string} family 表示字体的字符串
  5334. * @state
  5335. * 0: 当前有选中的节点
  5336. * -1: 当前没有选中的节点
  5337. * @return 返回首个选中节点的字体
  5338. */
  5339. fontfamily: kity.createClass("fontfamilyCommand", {
  5340. base: Command,
  5341. execute: function(km, family) {
  5342. var nodes = km.getSelectedNodes();
  5343. nodes.forEach(function(n) {
  5344. n.setData("font-family", family);
  5345. n.render();
  5346. km.layout();
  5347. });
  5348. },
  5349. queryState: function(km) {
  5350. return km.getSelectedNodes().length === 0 ? -1 : 0;
  5351. },
  5352. queryValue: function(km) {
  5353. var node = km.getSelectedNode();
  5354. if (node) return node.getData("font-family");
  5355. return null;
  5356. }
  5357. }),
  5358. /**
  5359. * @command FontSize
  5360. * @description 设置选中节点的字体大小
  5361. * @param {number} size 字体大小(px)
  5362. * @state
  5363. * 0: 当前有选中的节点
  5364. * -1: 当前没有选中的节点
  5365. * @return 返回首个选中节点的字体大小
  5366. */
  5367. fontsize: kity.createClass("fontsizeCommand", {
  5368. base: Command,
  5369. execute: function(km, size) {
  5370. var nodes = km.getSelectedNodes();
  5371. nodes.forEach(function(n) {
  5372. n.setData("font-size", size);
  5373. n.render();
  5374. km.layout(300);
  5375. });
  5376. },
  5377. queryState: function(km) {
  5378. return km.getSelectedNodes().length === 0 ? -1 : 0;
  5379. },
  5380. queryValue: function(km) {
  5381. var node = km.getSelectedNode();
  5382. if (node) return node.getData("font-size");
  5383. return null;
  5384. }
  5385. })
  5386. }
  5387. });
  5388. }
  5389. };
  5390. //src/module/hyperlink.js
  5391. _p[48] = {
  5392. value: function(require, exports, module) {
  5393. var kity = _p.r(17);
  5394. var utils = _p.r(33);
  5395. var Minder = _p.r(19);
  5396. var MinderNode = _p.r(21);
  5397. var Command = _p.r(9);
  5398. var Module = _p.r(20);
  5399. var Renderer = _p.r(27);
  5400. // jscs:disable maximumLineLength
  5401. var linkShapePath = "M16.614,10.224h-1.278c-1.668,0-3.07-1.07-3.599-2.556h4.877c0.707,0,1.278-0.571,1.278-1.278V3.834 c0-0.707-0.571-1.278-1.278-1.278h-4.877C12.266,1.071,13.668,0,15.336,0h1.278c2.116,0,3.834,1.716,3.834,3.834V6.39 C20.448,8.508,18.73,10.224,16.614,10.224z M5.112,5.112c0-0.707,0.573-1.278,1.278-1.278h7.668c0.707,0,1.278,0.571,1.278,1.278 S14.765,6.39,14.058,6.39H6.39C5.685,6.39,5.112,5.819,5.112,5.112z M2.556,3.834V6.39c0,0.707,0.573,1.278,1.278,1.278h4.877 c-0.528,1.486-1.932,2.556-3.599,2.556H3.834C1.716,10.224,0,8.508,0,6.39V3.834C0,1.716,1.716,0,3.834,0h1.278 c1.667,0,3.071,1.071,3.599,2.556H3.834C3.129,2.556,2.556,3.127,2.556,3.834z";
  5402. Module.register("hyperlink", {
  5403. commands: {
  5404. /**
  5405. * @command HyperLink
  5406. * @description 为选中的节点添加超链接
  5407. * @param {string} url 超链接的 URL,设置为 null 移除
  5408. * @param {string} title 超链接的说明
  5409. * @state
  5410. * 0: 当前有选中的节点
  5411. * -1: 当前没有选中的节点
  5412. * @return 返回首个选中节点的超链接信息,JSON 对象: `{url: url, title: title}`
  5413. */
  5414. hyperlink: kity.createClass("hyperlink", {
  5415. base: Command,
  5416. execute: function(km, url, title) {
  5417. var nodes = km.getSelectedNodes();
  5418. nodes.forEach(function(n) {
  5419. n.setData("hyperlink", url);
  5420. n.setData("hyperlinkTitle", url && title);
  5421. n.render();
  5422. });
  5423. km.layout();
  5424. },
  5425. queryState: function(km) {
  5426. var nodes = km.getSelectedNodes(), result = 0;
  5427. if (nodes.length === 0) {
  5428. return -1;
  5429. }
  5430. nodes.forEach(function(n) {
  5431. if (n && n.getData("hyperlink")) {
  5432. result = 0;
  5433. return false;
  5434. }
  5435. });
  5436. return result;
  5437. },
  5438. queryValue: function(km) {
  5439. var node = km.getSelectedNode();
  5440. return {
  5441. url: node.getData("hyperlink"),
  5442. title: node.getData("hyperlinkTitle")
  5443. };
  5444. }
  5445. })
  5446. },
  5447. renderers: {
  5448. right: kity.createClass("hyperlinkrender", {
  5449. base: Renderer,
  5450. create: function() {
  5451. var link = new kity.HyperLink();
  5452. var linkshape = new kity.Path();
  5453. var outline = new kity.Rect(24, 22, -2, -6, 4).fill("rgba(255, 255, 255, 0)");
  5454. linkshape.setPathData(linkShapePath).fill("#666");
  5455. link.addShape(outline);
  5456. link.addShape(linkshape);
  5457. link.setTarget("_blank");
  5458. link.setStyle("cursor", "pointer");
  5459. link.on("mouseover", function() {
  5460. outline.fill("rgba(255, 255, 200, .8)");
  5461. }).on("mouseout", function() {
  5462. outline.fill("rgba(255, 255, 255, 0)");
  5463. });
  5464. return link;
  5465. },
  5466. shouldRender: function(node) {
  5467. return node.getData("hyperlink");
  5468. },
  5469. update: function(link, node, box) {
  5470. var href = node.getData("hyperlink");
  5471. link.setHref("#");
  5472. var allowed = [ "^http:", "^https:", "^ftp:", "^mailto:" ];
  5473. for (var i = 0; i < allowed.length; i++) {
  5474. var regex = new RegExp(allowed[i]);
  5475. if (regex.test(href)) {
  5476. link.setHref(href);
  5477. break;
  5478. }
  5479. }
  5480. var title = node.getData("hyperlinkTitle");
  5481. if (title) {
  5482. title = [ title, "(", href, ")" ].join("");
  5483. } else {
  5484. title = href;
  5485. }
  5486. link.node.setAttributeNS("http://www.w3.org/1999/xlink", "title", title);
  5487. var spaceRight = node.getStyle("space-right");
  5488. link.setTranslate(box.right + spaceRight + 2, -5);
  5489. return new kity.Box({
  5490. x: box.right + spaceRight,
  5491. y: -11,
  5492. width: 24,
  5493. height: 22
  5494. });
  5495. }
  5496. })
  5497. }
  5498. });
  5499. }
  5500. };
  5501. //src/module/image-viewer.js
  5502. _p[49] = {
  5503. value: function(require, exports, module) {
  5504. var kity = _p.r(17);
  5505. var keymap = _p.r(15);
  5506. var Module = _p.r(20);
  5507. var Command = _p.r(9);
  5508. Module.register("ImageViewer", function() {
  5509. function createEl(name, classNames, children) {
  5510. var el = document.createElement(name);
  5511. addClass(el, classNames);
  5512. children && children.length && children.forEach(function(child) {
  5513. el.appendChild(child);
  5514. });
  5515. return el;
  5516. }
  5517. function on(el, event, handler) {
  5518. el.addEventListener(event, handler);
  5519. }
  5520. function addClass(el, classNames) {
  5521. classNames && classNames.split(" ").forEach(function(className) {
  5522. el.classList.add(className);
  5523. });
  5524. }
  5525. function removeClass(el, classNames) {
  5526. classNames && classNames.split(" ").forEach(function(className) {
  5527. el.classList.remove(className);
  5528. });
  5529. }
  5530. var ImageViewer = kity.createClass("ImageViewer", {
  5531. constructor: function() {
  5532. var btnClose = createEl("button", "km-image-viewer-btn km-image-viewer-close");
  5533. var btnSource = createEl("button", "km-image-viewer-btn km-image-viewer-source");
  5534. var image = this.image = createEl("img");
  5535. var toolbar = this.toolbar = createEl("div", "km-image-viewer-toolbar", [ btnSource, btnClose ]);
  5536. var container = createEl("div", "km-image-viewer-container", [ image ]);
  5537. var viewer = this.viewer = createEl("div", "km-image-viewer", [ toolbar, container ]);
  5538. this.hotkeyHandler = this.hotkeyHandler.bind(this);
  5539. on(btnClose, "click", this.close.bind(this));
  5540. on(btnSource, "click", this.viewSource.bind(this));
  5541. on(image, "click", this.zoomImage.bind(this));
  5542. on(viewer, "contextmenu", this.toggleToolbar.bind(this));
  5543. on(document, "keydown", this.hotkeyHandler);
  5544. },
  5545. dispose: function() {
  5546. this.close();
  5547. document.removeEventListener("remove", this.hotkeyHandler);
  5548. },
  5549. hotkeyHandler: function(e) {
  5550. if (!this.actived) {
  5551. return;
  5552. }
  5553. if (e.keyCode === keymap["esc"]) {
  5554. this.close();
  5555. }
  5556. },
  5557. toggleToolbar: function(e) {
  5558. e && e.preventDefault();
  5559. this.toolbar.classList.toggle("hidden");
  5560. },
  5561. zoomImage: function(restore) {
  5562. var image = this.image;
  5563. if (typeof restore === "boolean") {
  5564. restore && addClass(image, "limited");
  5565. } else {
  5566. image.classList.toggle("limited");
  5567. }
  5568. },
  5569. viewSource: function(src) {
  5570. window.open(this.image.src);
  5571. },
  5572. open: function(src) {
  5573. var input = document.querySelector("input");
  5574. if (input) {
  5575. input.focus();
  5576. input.blur();
  5577. }
  5578. this.image.src = src;
  5579. this.zoomImage(true);
  5580. document.body.appendChild(this.viewer);
  5581. this.actived = true;
  5582. },
  5583. close: function() {
  5584. this.image.src = "";
  5585. document.body.removeChild(this.viewer);
  5586. this.actived = false;
  5587. }
  5588. });
  5589. return {
  5590. init: function() {
  5591. this.viewer = new ImageViewer();
  5592. },
  5593. events: {
  5594. "normal.dblclick": function(e) {
  5595. var shape = e.kityEvent.targetShape;
  5596. if (shape.__KityClassName === "Image" && shape.url) {
  5597. this.viewer.open(shape.url);
  5598. }
  5599. }
  5600. }
  5601. };
  5602. });
  5603. }
  5604. };
  5605. //src/module/image.js
  5606. _p[50] = {
  5607. value: function(require, exports, module) {
  5608. var kity = _p.r(17);
  5609. var utils = _p.r(33);
  5610. var Minder = _p.r(19);
  5611. var MinderNode = _p.r(21);
  5612. var Command = _p.r(9);
  5613. var Module = _p.r(20);
  5614. var Renderer = _p.r(27);
  5615. Module.register("image", function() {
  5616. function loadImageSize(url, callback) {
  5617. var img = document.createElement("img");
  5618. img.onload = function() {
  5619. callback(img.width, img.height);
  5620. };
  5621. img.onerror = function() {
  5622. callback(null);
  5623. };
  5624. img.src = url;
  5625. }
  5626. function fitImageSize(width, height, maxWidth, maxHeight) {
  5627. var ratio = width / height, fitRatio = maxWidth / maxHeight;
  5628. // 宽高比大于最大尺寸的宽高比,以宽度为标准适应
  5629. if (width > maxWidth && ratio > fitRatio) {
  5630. width = maxWidth;
  5631. height = width / ratio;
  5632. } else if (height > maxHeight) {
  5633. height = maxHeight;
  5634. width = height * ratio;
  5635. }
  5636. return {
  5637. width: width | 0,
  5638. height: height | 0
  5639. };
  5640. }
  5641. /**
  5642. * @command Image
  5643. * @description 为选中的节点添加图片
  5644. * @param {string} url 图片的 URL,设置为 null 移除
  5645. * @param {string} title 图片的说明
  5646. * @state
  5647. * 0: 当前有选中的节点
  5648. * -1: 当前没有选中的节点
  5649. * @return 返回首个选中节点的图片信息,JSON 对象: `{url: url, title: title}`
  5650. */
  5651. var ImageCommand = kity.createClass("ImageCommand", {
  5652. base: Command,
  5653. execute: function(km, url, title) {
  5654. var nodes = km.getSelectedNodes();
  5655. loadImageSize(url, function(width, height) {
  5656. nodes.forEach(function(n) {
  5657. var size = fitImageSize(width, height, km.getOption("maxImageWidth"), km.getOption("maxImageHeight"));
  5658. n.setData("image", url);
  5659. n.setData("imageTitle", url && title);
  5660. n.setData("imageSize", url && size);
  5661. n.render();
  5662. });
  5663. km.fire("saveScene");
  5664. km.layout(300);
  5665. });
  5666. },
  5667. queryState: function(km) {
  5668. var nodes = km.getSelectedNodes(), result = 0;
  5669. if (nodes.length === 0) {
  5670. return -1;
  5671. }
  5672. nodes.forEach(function(n) {
  5673. if (n && n.getData("image")) {
  5674. result = 0;
  5675. return false;
  5676. }
  5677. });
  5678. return result;
  5679. },
  5680. queryValue: function(km) {
  5681. var node = km.getSelectedNode();
  5682. return {
  5683. url: node.getData("image"),
  5684. title: node.getData("imageTitle")
  5685. };
  5686. }
  5687. });
  5688. var ImageRenderer = kity.createClass("ImageRenderer", {
  5689. base: Renderer,
  5690. create: function(node) {
  5691. return new kity.Image(node.getData("image"));
  5692. },
  5693. shouldRender: function(node) {
  5694. return node.getData("image");
  5695. },
  5696. update: function(image, node, box) {
  5697. var url = node.getData("image");
  5698. var title = node.getData("imageTitle");
  5699. var size = node.getData("imageSize");
  5700. var spaceTop = node.getStyle("space-top");
  5701. if (!size) return;
  5702. if (title) {
  5703. image.node.setAttributeNS("http://www.w3.org/1999/xlink", "title", title);
  5704. }
  5705. var x = box.cx - size.width / 2;
  5706. var y = box.y - size.height - spaceTop;
  5707. image.setUrl(url).setX(x | 0).setY(y | 0).setWidth(size.width | 0).setHeight(size.height | 0);
  5708. return new kity.Box(x | 0, y | 0, size.width | 0, size.height | 0);
  5709. }
  5710. });
  5711. return {
  5712. defaultOptions: {
  5713. maxImageWidth: 200,
  5714. maxImageHeight: 200
  5715. },
  5716. commands: {
  5717. image: ImageCommand
  5718. },
  5719. renderers: {
  5720. top: ImageRenderer
  5721. }
  5722. };
  5723. });
  5724. }
  5725. };
  5726. //src/module/keynav.js
  5727. _p[51] = {
  5728. value: function(require, exports, module) {
  5729. var kity = _p.r(17);
  5730. var utils = _p.r(33);
  5731. var keymap = _p.r(15);
  5732. var Minder = _p.r(19);
  5733. var MinderNode = _p.r(21);
  5734. var Command = _p.r(9);
  5735. var Module = _p.r(20);
  5736. var Renderer = _p.r(27);
  5737. Module.register("KeyboardModule", function() {
  5738. var min = Math.min, max = Math.max, abs = Math.abs, sqrt = Math.sqrt, exp = Math.exp;
  5739. function buildPositionNetwork(root) {
  5740. var pointIndexes = [], p;
  5741. root.traverse(function(node) {
  5742. p = node.getLayoutBox();
  5743. // bugfix: 不应导航到收起的节点(判断其尺寸是否存在)
  5744. if (p.width && p.height) {
  5745. pointIndexes.push({
  5746. left: p.x,
  5747. top: p.y,
  5748. right: p.x + p.width,
  5749. bottom: p.y + p.height,
  5750. width: p.width,
  5751. height: p.height,
  5752. node: node
  5753. });
  5754. }
  5755. });
  5756. for (var i = 0; i < pointIndexes.length; i++) {
  5757. findClosestPointsFor(pointIndexes, i);
  5758. }
  5759. }
  5760. // 这是金泉的点子,赞!
  5761. // 求两个不相交矩形的最近距离
  5762. function getCoefedDistance(box1, box2) {
  5763. var xMin, xMax, yMin, yMax, xDist, yDist, dist, cx, cy;
  5764. xMin = min(box1.left, box2.left);
  5765. xMax = max(box1.right, box2.right);
  5766. yMin = min(box1.top, box2.top);
  5767. yMax = max(box1.bottom, box2.bottom);
  5768. xDist = xMax - xMin - box1.width - box2.width;
  5769. yDist = yMax - yMin - box1.height - box2.height;
  5770. if (xDist < 0) dist = yDist; else if (yDist < 0) dist = xDist; else dist = sqrt(xDist * xDist + yDist * yDist);
  5771. var node1 = box1.node;
  5772. var node2 = box2.node;
  5773. // sibling
  5774. if (node1.parent == node2.parent) {
  5775. dist /= 10;
  5776. }
  5777. // parent
  5778. if (node2.parent == node1) {
  5779. dist /= 5;
  5780. }
  5781. return dist;
  5782. }
  5783. function findClosestPointsFor(pointIndexes, iFind) {
  5784. var find = pointIndexes[iFind];
  5785. var most = {}, quad;
  5786. var current, dist;
  5787. for (var i = 0; i < pointIndexes.length; i++) {
  5788. if (i == iFind) continue;
  5789. current = pointIndexes[i];
  5790. dist = getCoefedDistance(current, find);
  5791. // left check
  5792. if (current.right < find.left) {
  5793. if (!most.left || dist < most.left.dist) {
  5794. most.left = {
  5795. dist: dist,
  5796. node: current.node
  5797. };
  5798. }
  5799. }
  5800. // right check
  5801. if (current.left > find.right) {
  5802. if (!most.right || dist < most.right.dist) {
  5803. most.right = {
  5804. dist: dist,
  5805. node: current.node
  5806. };
  5807. }
  5808. }
  5809. // top check
  5810. if (current.bottom < find.top) {
  5811. if (!most.top || dist < most.top.dist) {
  5812. most.top = {
  5813. dist: dist,
  5814. node: current.node
  5815. };
  5816. }
  5817. }
  5818. // bottom check
  5819. if (current.top > find.bottom) {
  5820. if (!most.down || dist < most.down.dist) {
  5821. most.down = {
  5822. dist: dist,
  5823. node: current.node
  5824. };
  5825. }
  5826. }
  5827. }
  5828. find.node._nearestNodes = {
  5829. right: most.right && most.right.node || null,
  5830. top: most.top && most.top.node || null,
  5831. left: most.left && most.left.node || null,
  5832. down: most.down && most.down.node || null
  5833. };
  5834. }
  5835. function navigateTo(km, direction) {
  5836. var referNode = km.getSelectedNode();
  5837. if (!referNode) {
  5838. km.select(km.getRoot());
  5839. buildPositionNetwork(km.getRoot());
  5840. return;
  5841. }
  5842. if (!referNode._nearestNodes) {
  5843. buildPositionNetwork(km.getRoot());
  5844. }
  5845. var nextNode = referNode._nearestNodes[direction];
  5846. if (nextNode) {
  5847. km.select(nextNode, true);
  5848. }
  5849. }
  5850. // 稀释用
  5851. var lastFrame;
  5852. return {
  5853. events: {
  5854. layoutallfinish: function() {
  5855. var root = this.getRoot();
  5856. buildPositionNetwork(root);
  5857. },
  5858. "normal.keydown readonly.keydown": function(e) {
  5859. var minder = this;
  5860. [ "left", "right", "up", "down" ].forEach(function(key) {
  5861. if (e.isShortcutKey(key)) {
  5862. navigateTo(minder, key == "up" ? "top" : key);
  5863. e.preventDefault();
  5864. }
  5865. });
  5866. }
  5867. }
  5868. };
  5869. });
  5870. }
  5871. };
  5872. //src/module/layout.js
  5873. /**
  5874. * @fileOverview
  5875. *
  5876. * 布局模块
  5877. *
  5878. * @author: techird
  5879. * @copyright: Baidu FEX, 2014
  5880. */
  5881. _p[52] = {
  5882. value: function(require, exports, module) {
  5883. var kity = _p.r(17);
  5884. var Command = _p.r(9);
  5885. var Module = _p.r(20);
  5886. /**
  5887. * @command Layout
  5888. * @description 设置选中节点的布局
  5889. * 允许使用的布局可以使用 `kityminder.Minder.getLayoutList()` 查询
  5890. * @param {string} name 布局的名称,设置为 null 则使用继承或默认的布局
  5891. * @state
  5892. * 0: 当前有选中的节点
  5893. * -1: 当前没有选中的节点
  5894. * @return 返回首个选中节点的布局名称
  5895. */
  5896. var LayoutCommand = kity.createClass("LayoutCommand", {
  5897. base: Command,
  5898. execute: function(minder, name) {
  5899. var nodes = minder.getSelectedNodes();
  5900. nodes.forEach(function(node) {
  5901. node.layout(name);
  5902. });
  5903. },
  5904. queryValue: function(minder) {
  5905. var node = minder.getSelectedNode();
  5906. if (node) {
  5907. return node.getData("layout");
  5908. }
  5909. },
  5910. queryState: function(minder) {
  5911. return minder.getSelectedNode() ? 0 : -1;
  5912. }
  5913. });
  5914. /**
  5915. * @command ResetLayout
  5916. * @description 重设选中节点的布局,如果当前没有选中的节点,重设整个脑图的布局
  5917. * @state
  5918. * 0: 始终可用
  5919. * @return 返回首个选中节点的布局名称
  5920. */
  5921. var ResetLayoutCommand = kity.createClass("ResetLayoutCommand", {
  5922. base: Command,
  5923. execute: function(minder) {
  5924. var nodes = minder.getSelectedNodes();
  5925. if (!nodes.length) nodes = [ minder.getRoot() ];
  5926. nodes.forEach(function(node) {
  5927. node.traverse(function(child) {
  5928. child.resetLayoutOffset();
  5929. if (!child.isRoot()) {
  5930. child.setData("layout", null);
  5931. }
  5932. });
  5933. });
  5934. minder.layout(300);
  5935. },
  5936. enableReadOnly: true
  5937. });
  5938. Module.register("LayoutModule", {
  5939. commands: {
  5940. layout: LayoutCommand,
  5941. resetlayout: ResetLayoutCommand
  5942. },
  5943. contextmenu: [ {
  5944. command: "resetlayout"
  5945. }, {
  5946. divider: true
  5947. } ],
  5948. commandShortcutKeys: {
  5949. resetlayout: "Ctrl+Shift+L"
  5950. }
  5951. });
  5952. }
  5953. };
  5954. //src/module/node.js
  5955. _p[53] = {
  5956. value: function(require, exports, module) {
  5957. var kity = _p.r(17);
  5958. var utils = _p.r(33);
  5959. var Minder = _p.r(19);
  5960. var MinderNode = _p.r(21);
  5961. var Command = _p.r(9);
  5962. var Module = _p.r(20);
  5963. var Renderer = _p.r(27);
  5964. /**
  5965. * @command AppendChildNode
  5966. * @description 添加子节点到选中的节点中
  5967. * @param {string|object} textOrData 要插入的节点的文本或数据
  5968. * @state
  5969. * 0: 当前有选中的节点
  5970. * -1: 当前没有选中的节点
  5971. */
  5972. var AppendChildCommand = kity.createClass("AppendChildCommand", {
  5973. base: Command,
  5974. execute: function(km, text) {
  5975. var parent = km.getSelectedNode();
  5976. if (!parent) {
  5977. return null;
  5978. }
  5979. var node = km.createNode(text, parent);
  5980. km.select(node, true);
  5981. if (parent.isExpanded()) {
  5982. node.render();
  5983. } else {
  5984. parent.expand();
  5985. parent.renderTree();
  5986. }
  5987. km.layout(600);
  5988. },
  5989. queryState: function(km) {
  5990. var selectedNode = km.getSelectedNode();
  5991. return selectedNode ? 0 : -1;
  5992. }
  5993. });
  5994. /**
  5995. * @command AppendSiblingNode
  5996. * @description 添加选中的节点的兄弟节点
  5997. * @param {string|object} textOrData 要添加的节点的文本或数据
  5998. * @state
  5999. * 0: 当前有选中的节点
  6000. * -1: 当前没有选中的节点
  6001. */
  6002. var AppendSiblingCommand = kity.createClass("AppendSiblingCommand", {
  6003. base: Command,
  6004. execute: function(km, text) {
  6005. var sibling = km.getSelectedNode();
  6006. var parent = sibling.parent;
  6007. if (!parent) {
  6008. return km.execCommand("AppendChildNode", text);
  6009. }
  6010. var node = km.createNode(text, parent, sibling.getIndex() + 1);
  6011. node.setGlobalLayoutTransform(sibling.getGlobalLayoutTransform());
  6012. km.select(node, true);
  6013. node.render();
  6014. km.layout(600);
  6015. },
  6016. queryState: function(km) {
  6017. var selectedNode = km.getSelectedNode();
  6018. return selectedNode ? 0 : -1;
  6019. }
  6020. });
  6021. /**
  6022. * @command RemoveNode
  6023. * @description 移除选中的节点
  6024. * @state
  6025. * 0: 当前有选中的节点
  6026. * -1: 当前没有选中的节点
  6027. */
  6028. var RemoveNodeCommand = kity.createClass("RemoverNodeCommand", {
  6029. base: Command,
  6030. execute: function(km) {
  6031. var nodes = km.getSelectedNodes();
  6032. var ancestor = MinderNode.getCommonAncestor.apply(null, nodes);
  6033. var index = nodes[0].getIndex();
  6034. nodes.forEach(function(node) {
  6035. if (!node.isRoot()) km.removeNode(node);
  6036. });
  6037. if (nodes.length == 1) {
  6038. var selectBack = ancestor.children[index - 1] || ancestor.children[index];
  6039. km.select(selectBack || ancestor || km.getRoot(), true);
  6040. } else {
  6041. km.select(ancestor || km.getRoot(), true);
  6042. }
  6043. km.layout(600);
  6044. },
  6045. queryState: function(km) {
  6046. var selectedNode = km.getSelectedNode();
  6047. return selectedNode && !selectedNode.isRoot() ? 0 : -1;
  6048. }
  6049. });
  6050. var AppendParentCommand = kity.createClass("AppendParentCommand", {
  6051. base: Command,
  6052. execute: function(km, text) {
  6053. var nodes = km.getSelectedNodes();
  6054. nodes.sort(function(a, b) {
  6055. return a.getIndex() - b.getIndex();
  6056. });
  6057. var parent = nodes[0].parent;
  6058. var newParent = km.createNode(text, parent, nodes[0].getIndex());
  6059. nodes.forEach(function(node) {
  6060. newParent.appendChild(node);
  6061. });
  6062. newParent.setGlobalLayoutTransform(nodes[nodes.length >> 1].getGlobalLayoutTransform());
  6063. km.select(newParent, true);
  6064. km.layout(600);
  6065. },
  6066. queryState: function(km) {
  6067. var nodes = km.getSelectedNodes();
  6068. if (!nodes.length) return -1;
  6069. var parent = nodes[0].parent;
  6070. if (!parent) return -1;
  6071. for (var i = 1; i < nodes.length; i++) {
  6072. if (nodes[i].parent != parent) return -1;
  6073. }
  6074. return 0;
  6075. }
  6076. });
  6077. Module.register("NodeModule", function() {
  6078. return {
  6079. commands: {
  6080. AppendChildNode: AppendChildCommand,
  6081. AppendSiblingNode: AppendSiblingCommand,
  6082. RemoveNode: RemoveNodeCommand,
  6083. AppendParentNode: AppendParentCommand
  6084. },
  6085. commandShortcutKeys: {
  6086. appendsiblingnode: "normal::Enter",
  6087. appendchildnode: "normal::Insert|Tab",
  6088. appendparentnode: "normal::Shift+Tab|normal::Shift+Insert",
  6089. removenode: "normal::Del|Backspace"
  6090. }
  6091. };
  6092. });
  6093. }
  6094. };
  6095. //src/module/note.js
  6096. /**
  6097. * @fileOverview
  6098. *
  6099. * 支持节点详细信息(HTML)格式
  6100. *
  6101. * @author: techird
  6102. * @copyright: Baidu FEX, 2014
  6103. */
  6104. _p[54] = {
  6105. value: function(require, exports, module) {
  6106. var kity = _p.r(17);
  6107. var utils = _p.r(33);
  6108. var Minder = _p.r(19);
  6109. var MinderNode = _p.r(21);
  6110. var Command = _p.r(9);
  6111. var Module = _p.r(20);
  6112. var Renderer = _p.r(27);
  6113. Module.register("NoteModule", function() {
  6114. var NOTE_PATH = "M9,9H3V8h6L9,9L9,9z M9,7H3V6h6V7z M9,5H3V4h6V5z M8.5,11H2V2h8v7.5 M9,12l2-2V1H1v11";
  6115. /**
  6116. * @command Note
  6117. * @description 设置节点的备注信息
  6118. * @param {string} note 要设置的备注信息,设置为 null 则移除备注信息
  6119. * @state
  6120. * 0: 当前有选中的节点
  6121. * -1: 当前没有选中的节点
  6122. */
  6123. var NoteCommand = kity.createClass("NoteCommand", {
  6124. base: Command,
  6125. execute: function(minder, note) {
  6126. var node = minder.getSelectedNode();
  6127. node.setData("note", note);
  6128. node.render();
  6129. node.getMinder().layout(300);
  6130. },
  6131. queryState: function(minder) {
  6132. return minder.getSelectedNodes().length === 1 ? 0 : -1;
  6133. },
  6134. queryValue: function(minder) {
  6135. var node = minder.getSelectedNode();
  6136. return node && node.getData("note");
  6137. }
  6138. });
  6139. var NoteIcon = kity.createClass("NoteIcon", {
  6140. base: kity.Group,
  6141. constructor: function() {
  6142. this.callBase();
  6143. this.width = 16;
  6144. this.height = 17;
  6145. this.rect = new kity.Rect(16, 17, .5, -8.5, 2).fill("transparent");
  6146. this.path = new kity.Path().setPathData(NOTE_PATH).setTranslate(2.5, -6.5);
  6147. this.addShapes([ this.rect, this.path ]);
  6148. this.on("mouseover", function() {
  6149. this.rect.fill("rgba(255, 255, 200, .8)");
  6150. }).on("mouseout", function() {
  6151. this.rect.fill("transparent");
  6152. });
  6153. this.setStyle("cursor", "pointer");
  6154. }
  6155. });
  6156. var NoteIconRenderer = kity.createClass("NoteIconRenderer", {
  6157. base: Renderer,
  6158. create: function(node) {
  6159. var icon = new NoteIcon();
  6160. icon.on("mousedown", function(e) {
  6161. e.preventDefault();
  6162. node.getMinder().fire("editnoterequest");
  6163. });
  6164. icon.on("mouseover", function() {
  6165. node.getMinder().fire("shownoterequest", {
  6166. node: node,
  6167. icon: icon
  6168. });
  6169. });
  6170. icon.on("mouseout", function() {
  6171. node.getMinder().fire("hidenoterequest", {
  6172. node: node,
  6173. icon: icon
  6174. });
  6175. });
  6176. return icon;
  6177. },
  6178. shouldRender: function(node) {
  6179. return node.getData("note");
  6180. },
  6181. update: function(icon, node, box) {
  6182. var x = box.right + node.getStyle("space-left");
  6183. var y = box.cy;
  6184. icon.path.fill(node.getStyle("color"));
  6185. icon.setTranslate(x, y);
  6186. return new kity.Box(x, Math.round(y - icon.height / 2), icon.width, icon.height);
  6187. }
  6188. });
  6189. return {
  6190. renderers: {
  6191. right: NoteIconRenderer
  6192. },
  6193. commands: {
  6194. note: NoteCommand
  6195. }
  6196. };
  6197. });
  6198. }
  6199. };
  6200. //src/module/outline.js
  6201. _p[55] = {
  6202. value: function(require, exports, module) {
  6203. var kity = _p.r(17);
  6204. var utils = _p.r(33);
  6205. var Minder = _p.r(19);
  6206. var MinderNode = _p.r(21);
  6207. var Command = _p.r(9);
  6208. var Module = _p.r(20);
  6209. var Renderer = _p.r(27);
  6210. var OutlineRenderer = kity.createClass("OutlineRenderer", {
  6211. base: Renderer,
  6212. create: function(node) {
  6213. var outline = new kity.Rect().setId(utils.uuid("node_outline"));
  6214. this.bringToBack = true;
  6215. return outline;
  6216. },
  6217. update: function(outline, node, box) {
  6218. var shape = node.getStyle("shape");
  6219. var paddingLeft = node.getStyle("padding-left"), paddingRight = node.getStyle("padding-right"), paddingTop = node.getStyle("padding-top"), paddingBottom = node.getStyle("padding-bottom");
  6220. var outlineBox = {
  6221. x: box.x - paddingLeft,
  6222. y: box.y - paddingTop,
  6223. width: box.width + paddingLeft + paddingRight,
  6224. height: box.height + paddingTop + paddingBottom
  6225. };
  6226. var radius = node.getStyle("radius");
  6227. // 天盘图圆形的情况
  6228. if (shape && shape == "circle") {
  6229. var p = Math.pow;
  6230. var r = Math.round;
  6231. radius = r(Math.sqrt(p(outlineBox.width, 2) + p(outlineBox.height, 2)) / 2);
  6232. outlineBox.x = box.cx - radius;
  6233. outlineBox.y = box.cy - radius;
  6234. outlineBox.width = 2 * radius;
  6235. outlineBox.height = 2 * radius;
  6236. }
  6237. var prefix = node.isSelected() ? node.getMinder().isFocused() ? "selected-" : "blur-selected-" : "";
  6238. outline.setPosition(outlineBox.x, outlineBox.y).setSize(outlineBox.width, outlineBox.height).setRadius(radius).fill(node.getData("background") || node.getStyle(prefix + "background") || node.getStyle("background")).stroke(node.getStyle(prefix + "stroke" || node.getStyle("stroke")), node.getStyle(prefix + "stroke-width"));
  6239. return new kity.Box(outlineBox);
  6240. }
  6241. });
  6242. var ShadowRenderer = kity.createClass("ShadowRenderer", {
  6243. base: Renderer,
  6244. create: function(node) {
  6245. this.bringToBack = true;
  6246. return new kity.Rect();
  6247. },
  6248. shouldRender: function(node) {
  6249. return node.getStyle("shadow");
  6250. },
  6251. update: function(shadow, node, box) {
  6252. shadow.setPosition(box.x + 4, box.y + 5).fill(node.getStyle("shadow"));
  6253. var shape = node.getStyle("shape");
  6254. if (!shape) {
  6255. shadow.setSize(box.width, box.height);
  6256. shadow.setRadius(node.getStyle("radius"));
  6257. } else if (shape == "circle") {
  6258. var width = Math.max(box.width, box.height);
  6259. shadow.setSize(width, width);
  6260. shadow.setRadius(width / 2);
  6261. }
  6262. }
  6263. });
  6264. var marker = new kity.Marker();
  6265. marker.setWidth(10);
  6266. marker.setHeight(12);
  6267. marker.setRef(0, 0);
  6268. marker.setViewBox(-6, -4, 8, 10);
  6269. marker.addShape(new kity.Path().setPathData("M-5-3l5,3,-5,3").stroke("#33ffff"));
  6270. var wireframeOption = /wire/.test(window.location.href);
  6271. var WireframeRenderer = kity.createClass("WireframeRenderer", {
  6272. base: Renderer,
  6273. create: function() {
  6274. var wireframe = new kity.Group();
  6275. var oxy = this.oxy = new kity.Path().stroke("#f6f").setPathData("M0,-50L0,50M-50,0L50,0");
  6276. var box = this.wireframe = new kity.Rect().stroke("lightgreen");
  6277. var vectorIn = this.vectorIn = new kity.Path().stroke("#66ffff");
  6278. var vectorOut = this.vectorOut = new kity.Path().stroke("#66ffff");
  6279. vectorIn.setMarker(marker, "end");
  6280. vectorOut.setMarker(marker, "end");
  6281. return wireframe.addShapes([ oxy, box, vectorIn, vectorOut ]);
  6282. },
  6283. shouldRender: function() {
  6284. return wireframeOption;
  6285. },
  6286. update: function(created, node, box) {
  6287. this.wireframe.setPosition(box.x, box.y).setSize(box.width, box.height);
  6288. var pin = node.getVertexIn();
  6289. var pout = node.getVertexOut();
  6290. var vin = node.getLayoutVectorIn().normalize(30);
  6291. var vout = node.getLayoutVectorOut().normalize(30);
  6292. this.vectorIn.setPathData([ "M", pin.offset(vin.reverse()), "L", pin ]);
  6293. this.vectorOut.setPathData([ "M", pout, "l", vout ]);
  6294. }
  6295. });
  6296. Module.register("OutlineModule", function() {
  6297. return {
  6298. events: !wireframeOption ? null : {
  6299. ready: function() {
  6300. this.getPaper().addResource(marker);
  6301. },
  6302. layoutallfinish: function() {
  6303. this.getRoot().traverse(function(node) {
  6304. node.getRenderer("WireframeRenderer").update(null, node, node.getContentBox());
  6305. });
  6306. }
  6307. },
  6308. renderers: {
  6309. outline: OutlineRenderer,
  6310. outside: [ ShadowRenderer, WireframeRenderer ]
  6311. }
  6312. };
  6313. });
  6314. }
  6315. };
  6316. //src/module/priority.js
  6317. _p[56] = {
  6318. value: function(require, exports, module) {
  6319. var kity = _p.r(17);
  6320. var utils = _p.r(33);
  6321. var Minder = _p.r(19);
  6322. var MinderNode = _p.r(21);
  6323. var Command = _p.r(9);
  6324. var Module = _p.r(20);
  6325. var Renderer = _p.r(27);
  6326. Module.register("PriorityModule", function() {
  6327. var minder = this;
  6328. // Designed by Akikonata
  6329. // [MASK, BACK]
  6330. var PRIORITY_COLORS = [ null, [ "#FF1200", "#840023" ], // 1 - red
  6331. [ "#0074FF", "#01467F" ], // 2 - blue
  6332. [ "#00AF00", "#006300" ], // 3 - green
  6333. [ "#FF962E", "#B25000" ], // 4 - orange
  6334. [ "#A464FF", "#4720C4" ], // 5 - purple
  6335. [ "#A3A3A3", "#515151" ], // 6,7,8,9 - gray
  6336. [ "#A3A3A3", "#515151" ], [ "#A3A3A3", "#515151" ], [ "#A3A3A3", "#515151" ] ];
  6337. // hue from 1 to 5
  6338. // jscs:disable maximumLineLength
  6339. var BACK_PATH = "M0,13c0,3.866,3.134,7,7,7h6c3.866,0,7-3.134,7-7V7H0V13z";
  6340. var MASK_PATH = "M20,10c0,3.866-3.134,7-7,7H7c-3.866,0-7-3.134-7-7V7c0-3.866,3.134-7,7-7h6c3.866,0,7,3.134,7,7V10z";
  6341. var PRIORITY_DATA = "priority";
  6342. // 优先级图标的图形
  6343. var PriorityIcon = kity.createClass("PriorityIcon", {
  6344. base: kity.Group,
  6345. constructor: function() {
  6346. this.callBase();
  6347. this.setSize(20);
  6348. this.create();
  6349. this.setId(utils.uuid("node_priority"));
  6350. },
  6351. setSize: function(size) {
  6352. this.width = this.height = size;
  6353. },
  6354. create: function() {
  6355. var white, back, mask, number;
  6356. // 4 layer
  6357. white = new kity.Path().setPathData(MASK_PATH).fill("white");
  6358. back = new kity.Path().setPathData(BACK_PATH).setTranslate(.5, .5);
  6359. mask = new kity.Path().setPathData(MASK_PATH).setOpacity(.8).setTranslate(.5, .5);
  6360. number = new kity.Text().setX(this.width / 2 - .5).setY(this.height / 2).setTextAnchor("middle").setVerticalAlign("middle").setFontItalic(true).setFontSize(12).fill("white");
  6361. this.addShapes([ back, mask, number ]);
  6362. this.mask = mask;
  6363. this.back = back;
  6364. this.number = number;
  6365. },
  6366. setValue: function(value) {
  6367. var back = this.back, mask = this.mask, number = this.number;
  6368. var color = PRIORITY_COLORS[value];
  6369. if (color) {
  6370. back.fill(color[1]);
  6371. mask.fill(color[0]);
  6372. }
  6373. number.setContent(value);
  6374. }
  6375. });
  6376. /**
  6377. * @command Priority
  6378. * @description 设置节点的优先级信息
  6379. * @param {number} value 要设置的优先级(添加一个优先级小图标)
  6380. * 取值为 0 移除优先级信息;
  6381. * 取值为 1 - 9 设置优先级,超过 9 的优先级不渲染
  6382. * @state
  6383. * 0: 当前有选中的节点
  6384. * -1: 当前没有选中的节点
  6385. */
  6386. var PriorityCommand = kity.createClass("SetPriorityCommand", {
  6387. base: Command,
  6388. execute: function(km, value) {
  6389. var nodes = km.getSelectedNodes();
  6390. for (var i = 0; i < nodes.length; i++) {
  6391. nodes[i].setData(PRIORITY_DATA, value || null).render();
  6392. }
  6393. km.layout();
  6394. },
  6395. queryValue: function(km) {
  6396. var nodes = km.getSelectedNodes();
  6397. var val;
  6398. for (var i = 0; i < nodes.length; i++) {
  6399. val = nodes[i].getData(PRIORITY_DATA);
  6400. if (val) break;
  6401. }
  6402. return val || null;
  6403. },
  6404. queryState: function(km) {
  6405. return km.getSelectedNodes().length ? 0 : -1;
  6406. }
  6407. });
  6408. return {
  6409. commands: {
  6410. priority: PriorityCommand
  6411. },
  6412. renderers: {
  6413. left: kity.createClass("PriorityRenderer", {
  6414. base: Renderer,
  6415. create: function(node) {
  6416. return new PriorityIcon();
  6417. },
  6418. shouldRender: function(node) {
  6419. return node.getData(PRIORITY_DATA);
  6420. },
  6421. update: function(icon, node, box) {
  6422. var data = node.getData(PRIORITY_DATA);
  6423. var spaceLeft = node.getStyle("space-left"), x, y;
  6424. icon.setValue(data);
  6425. x = box.left - icon.width - spaceLeft;
  6426. y = -icon.height / 2;
  6427. icon.setTranslate(x, y);
  6428. return new kity.Box({
  6429. x: x,
  6430. y: y,
  6431. width: icon.width,
  6432. height: icon.height
  6433. });
  6434. }
  6435. })
  6436. }
  6437. };
  6438. });
  6439. }
  6440. };
  6441. //src/module/progress.js
  6442. _p[57] = {
  6443. value: function(require, exports, module) {
  6444. var kity = _p.r(17);
  6445. var utils = _p.r(33);
  6446. var Minder = _p.r(19);
  6447. var MinderNode = _p.r(21);
  6448. var Command = _p.r(9);
  6449. var Module = _p.r(20);
  6450. var Renderer = _p.r(27);
  6451. Module.register("ProgressModule", function() {
  6452. var minder = this;
  6453. var PROGRESS_DATA = "progress";
  6454. // Designed by Akikonata
  6455. var BG_COLOR = "#FFED83";
  6456. var PIE_COLOR = "#43BC00";
  6457. var SHADOW_PATH = "M10,3c4.418,0,8,3.582,8,8h1c0-5.523-3.477-10-9-10S1,5.477,1,11h1C2,6.582,5.582,3,10,3z";
  6458. var SHADOW_COLOR = "#8E8E8E";
  6459. // jscs:disable maximumLineLength
  6460. var FRAME_PATH = "M10,0C4.477,0,0,4.477,0,10c0,5.523,4.477,10,10,10s10-4.477,10-10C20,4.477,15.523,0,10,0zM10,18c-4.418,0-8-3.582-8-8s3.582-8,8-8s8,3.582,8,8S14.418,18,10,18z";
  6461. var FRAME_GRAD = new kity.LinearGradient().pipe(function(g) {
  6462. g.setStartPosition(0, 0);
  6463. g.setEndPosition(0, 1);
  6464. g.addStop(0, "#fff");
  6465. g.addStop(1, "#ccc");
  6466. });
  6467. var CHECK_PATH = "M15.812,7.896l-6.75,6.75l-4.5-4.5L6.25,8.459l2.812,2.803l5.062-5.053L15.812,7.896z";
  6468. var CHECK_COLOR = "#EEE";
  6469. minder.getPaper().addResource(FRAME_GRAD);
  6470. // 进度图标的图形
  6471. var ProgressIcon = kity.createClass("ProgressIcon", {
  6472. base: kity.Group,
  6473. constructor: function(value) {
  6474. this.callBase();
  6475. this.setSize(20);
  6476. this.create();
  6477. this.setValue(value);
  6478. this.setId(utils.uuid("node_progress"));
  6479. this.translate(.5, .5);
  6480. },
  6481. setSize: function(size) {
  6482. this.width = this.height = size;
  6483. },
  6484. create: function() {
  6485. var bg, pie, shadow, frame, check;
  6486. bg = new kity.Circle(9).fill(BG_COLOR);
  6487. pie = new kity.Pie(9, 0).fill(PIE_COLOR);
  6488. shadow = new kity.Path().setPathData(SHADOW_PATH).setTranslate(-10, -10).fill(SHADOW_COLOR);
  6489. frame = new kity.Path().setTranslate(-10, -10).setPathData(FRAME_PATH).fill(FRAME_GRAD);
  6490. check = new kity.Path().setTranslate(-10, -10).setPathData(CHECK_PATH).fill(CHECK_COLOR);
  6491. this.addShapes([ bg, pie, shadow, check, frame ]);
  6492. this.pie = pie;
  6493. this.check = check;
  6494. },
  6495. setValue: function(value) {
  6496. this.pie.setAngle(-360 * (value - 1) / 8);
  6497. this.check.setVisible(value == 9);
  6498. }
  6499. });
  6500. /**
  6501. * @command Progress
  6502. * @description 设置节点的进度信息(添加一个进度小图标)
  6503. * @param {number} value 要设置的进度
  6504. * 取值为 0 移除进度信息;
  6505. * 取值为 1 表示未开始;
  6506. * 取值为 2 表示完成 1/8;
  6507. * 取值为 3 表示完成 2/8;
  6508. * 取值为 4 表示完成 3/8;
  6509. * 其余类推,取值为 9 表示全部完成
  6510. * @state
  6511. * 0: 当前有选中的节点
  6512. * -1: 当前没有选中的节点
  6513. */
  6514. var ProgressCommand = kity.createClass("ProgressCommand", {
  6515. base: Command,
  6516. execute: function(km, value) {
  6517. var nodes = km.getSelectedNodes();
  6518. for (var i = 0; i < nodes.length; i++) {
  6519. nodes[i].setData(PROGRESS_DATA, value || null).render();
  6520. }
  6521. km.layout();
  6522. },
  6523. queryValue: function(km) {
  6524. var nodes = km.getSelectedNodes();
  6525. var val;
  6526. for (var i = 0; i < nodes.length; i++) {
  6527. val = nodes[i].getData(PROGRESS_DATA);
  6528. if (val) break;
  6529. }
  6530. return val || null;
  6531. },
  6532. queryState: function(km) {
  6533. return km.getSelectedNodes().length ? 0 : -1;
  6534. }
  6535. });
  6536. return {
  6537. commands: {
  6538. progress: ProgressCommand
  6539. },
  6540. renderers: {
  6541. left: kity.createClass("ProgressRenderer", {
  6542. base: Renderer,
  6543. create: function(node) {
  6544. return new ProgressIcon();
  6545. },
  6546. shouldRender: function(node) {
  6547. return node.getData(PROGRESS_DATA);
  6548. },
  6549. update: function(icon, node, box) {
  6550. var data = node.getData(PROGRESS_DATA);
  6551. var spaceLeft = node.getStyle("space-left");
  6552. var x, y;
  6553. icon.setValue(data);
  6554. x = box.left - icon.width - spaceLeft;
  6555. y = -icon.height / 2;
  6556. icon.setTranslate(x + icon.width / 2, y + icon.height / 2);
  6557. return new kity.Box(x, y, icon.width, icon.height);
  6558. }
  6559. })
  6560. }
  6561. };
  6562. });
  6563. }
  6564. };
  6565. //src/module/resource.js
  6566. _p[58] = {
  6567. value: function(require, exports, module) {
  6568. var kity = _p.r(17);
  6569. var utils = _p.r(33);
  6570. var Minder = _p.r(19);
  6571. var MinderNode = _p.r(21);
  6572. var Command = _p.r(9);
  6573. var Module = _p.r(20);
  6574. var Renderer = _p.r(27);
  6575. Module.register("Resource", function() {
  6576. // String Hash
  6577. // https://github.com/drostie/sha3-js/edit/master/blake32.min.js
  6578. var blake32 = function() {
  6579. var k, g, r, l, m, o, p, q, t, w, x;
  6580. x = 4 * (1 << 30);
  6581. k = [ 1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225 ];
  6582. m = [ 608135816, 2242054355, 320440878, 57701188, 2752067618, 698298832, 137296536, 3964562569, 1160258022, 953160567, 3193202383, 887688300, 3232508343, 3380367581, 1065670069, 3041331479 ];
  6583. w = function(i) {
  6584. if (i < 0) {
  6585. i += x;
  6586. }
  6587. return ("00000000" + i.toString(16)).slice(-8);
  6588. };
  6589. o = [ [ 16, 50, 84, 118, 152, 186, 220, 254 ], [ 174, 132, 249, 109, 193, 32, 123, 53 ], [ 139, 12, 37, 223, 234, 99, 23, 73 ], [ 151, 19, 205, 235, 98, 165, 4, 143 ], [ 9, 117, 66, 250, 30, 203, 134, 211 ], [ 194, 166, 176, 56, 212, 87, 239, 145 ], [ 92, 241, 222, 164, 112, 54, 41, 184 ], [ 189, 231, 28, 147, 5, 79, 104, 162 ], [ 246, 158, 59, 128, 44, 125, 65, 90 ], [ 42, 72, 103, 81, 191, 233, 195, 13 ] ];
  6590. p = function(a, b, n) {
  6591. var s = q[a] ^ q[b];
  6592. q[a] = s >>> n | s << 32 - n;
  6593. };
  6594. g = function(i, a, b, c, d) {
  6595. var u = l + o[r][i] % 16, v = l + (o[r][i] >> 4);
  6596. a %= 4;
  6597. b = 4 + b % 4;
  6598. c = 8 + c % 4;
  6599. d = 12 + d % 4;
  6600. q[a] += q[b] + (t[u] ^ m[v % 16]);
  6601. p(d, a, 16);
  6602. q[c] += q[d];
  6603. p(b, c, 12);
  6604. q[a] += q[b] + (t[v] ^ m[u % 16]);
  6605. p(d, a, 8);
  6606. q[c] += q[d];
  6607. p(b, c, 7);
  6608. };
  6609. return function(a, b) {
  6610. if (!(b instanceof Array && b.length === 4)) {
  6611. b = [ 0, 0, 0, 0 ];
  6612. }
  6613. var c, d, e, L, f, h, j, i;
  6614. d = k.slice(0);
  6615. c = m.slice(0, 8);
  6616. for (r = 0; r < 4; r += 1) {
  6617. c[r] ^= b[r];
  6618. }
  6619. e = a.length * 16;
  6620. f = e % 512 > 446 || e % 512 === 0 ? 0 : e;
  6621. if (e % 512 === 432) {
  6622. a += "老";
  6623. } else {
  6624. a += "耀";
  6625. while (a.length % 32 !== 27) {
  6626. a += "\0";
  6627. }
  6628. a += "";
  6629. }
  6630. t = [];
  6631. for (i = 0; i < a.length; i += 2) {
  6632. t.push(a.charCodeAt(i) * 65536 + a.charCodeAt(i + 1));
  6633. }
  6634. t.push(0);
  6635. t.push(e);
  6636. h = t.length - 16;
  6637. j = 0;
  6638. for (l = 0; l < t.length; l += 16) {
  6639. j += 512;
  6640. L = l === h ? f : Math.min(e, j);
  6641. q = d.concat(c);
  6642. q[12] ^= L;
  6643. q[13] ^= L;
  6644. for (r = 0; r < 10; r += 1) {
  6645. for (i = 0; i < 8; i += 1) {
  6646. if (i < 4) {
  6647. g(i, i, i, i, i);
  6648. } else {
  6649. g(i, i, i + 1, i + 2, i + 3);
  6650. }
  6651. }
  6652. }
  6653. for (i = 0; i < 8; i += 1) {
  6654. d[i] ^= b[i % 4] ^ q[i] ^ q[i + 8];
  6655. }
  6656. }
  6657. return d.map(w).join("");
  6658. };
  6659. }();
  6660. /**
  6661. * 自动使用的颜色序列
  6662. */
  6663. var RESOURCE_COLOR_SERIES = [ 51, 303, 75, 200, 157, 0, 26, 254 ].map(function(h) {
  6664. return kity.Color.createHSL(h, 100, 85);
  6665. });
  6666. /**
  6667. * 在 Minder 上拓展一些关于资源的支持接口
  6668. */
  6669. kity.extendClass(Minder, {
  6670. /**
  6671. * 获取字符串的哈希值
  6672. *
  6673. * @param {String} str
  6674. * @return {Number} hashCode
  6675. */
  6676. getHashCode: function(str) {
  6677. str = blake32(str);
  6678. var hash = 1315423911, i, ch;
  6679. for (i = str.length - 1; i >= 0; i--) {
  6680. ch = str.charCodeAt(i);
  6681. hash ^= (hash << 5) + ch + (hash >> 2);
  6682. }
  6683. return hash & 2147483647;
  6684. },
  6685. /**
  6686. * 获取脑图中某个资源对应的颜色
  6687. *
  6688. * 如果存在同名资源,则返回已经分配给该资源的颜色,否则分配给该资源一个颜色,并且返回
  6689. *
  6690. * 如果资源数超过颜色序列数量,返回哈希颜色
  6691. *
  6692. * @param {String} resource 资源名称
  6693. * @return {Color}
  6694. */
  6695. getResourceColor: function(resource) {
  6696. var colorMapping = this._getResourceColorIndexMapping();
  6697. var nextIndex;
  6698. if (!Object.prototype.hasOwnProperty.call(colorMapping, resource)) {
  6699. // 找不到找下个可用索引
  6700. nextIndex = this._getNextResourceColorIndex();
  6701. colorMapping[resource] = nextIndex;
  6702. }
  6703. // 资源过多,找不到可用索引颜色,统一返回哈希函数得到的颜色
  6704. return RESOURCE_COLOR_SERIES[colorMapping[resource]] || kity.Color.createHSL(Math.floor(this.getHashCode(resource) / 2147483647 * 359), 100, 85);
  6705. },
  6706. /**
  6707. * 获得已使用的资源的列表
  6708. *
  6709. * @return {Array}
  6710. */
  6711. getUsedResource: function() {
  6712. var mapping = this._getResourceColorIndexMapping();
  6713. var used = [], resource;
  6714. for (resource in mapping) {
  6715. if (Object.prototype.hasOwnProperty.call(mapping, resource)) {
  6716. used.push(resource);
  6717. }
  6718. }
  6719. return used;
  6720. },
  6721. /**
  6722. * 获取脑图下一个可用的资源颜色索引
  6723. *
  6724. * @return {int}
  6725. */
  6726. _getNextResourceColorIndex: function() {
  6727. // 获取现有颜色映射
  6728. // resource => color_index
  6729. var colorMapping = this._getResourceColorIndexMapping();
  6730. var resource, used, i;
  6731. used = [];
  6732. // 抽取已经使用的值到 used 数组
  6733. for (resource in colorMapping) {
  6734. if (Object.prototype.hasOwnProperty.call(colorMapping, resource)) {
  6735. used.push(colorMapping[resource]);
  6736. }
  6737. }
  6738. // 枚举所有的可用值,如果还没被使用,返回
  6739. for (i = 0; i < RESOURCE_COLOR_SERIES.length; i++) {
  6740. if (!~used.indexOf(i)) return i;
  6741. }
  6742. // 没有可用的颜色了
  6743. return -1;
  6744. },
  6745. // 获取现有颜色映射
  6746. // resource => color_index
  6747. _getResourceColorIndexMapping: function() {
  6748. return this._resourceColorMapping || (this._resourceColorMapping = {});
  6749. }
  6750. });
  6751. /**
  6752. * @class 设置资源的命令
  6753. *
  6754. * @example
  6755. *
  6756. * // 设置选中节点资源为 "张三"
  6757. * minder.execCommand('resource', ['张三']);
  6758. *
  6759. * // 添加资源 "李四" 到选中节点
  6760. * var resource = minder.queryCommandValue();
  6761. * resource.push('李四');
  6762. * minder.execCommand('resource', resource);
  6763. *
  6764. * // 清除选中节点的资源
  6765. * minder.execCommand('resource', null);
  6766. */
  6767. var ResourceCommand = kity.createClass("ResourceCommand", {
  6768. base: Command,
  6769. execute: function(minder, resource) {
  6770. var nodes = minder.getSelectedNodes();
  6771. if (typeof resource == "string") {
  6772. resource = [ resource ];
  6773. }
  6774. nodes.forEach(function(node) {
  6775. node.setData("resource", resource).render();
  6776. });
  6777. minder.layout(200);
  6778. },
  6779. queryValue: function(minder) {
  6780. var nodes = minder.getSelectedNodes();
  6781. var resource = [];
  6782. nodes.forEach(function(node) {
  6783. var nodeResource = node.getData("resource");
  6784. if (!nodeResource) return;
  6785. nodeResource.forEach(function(name) {
  6786. if (!~resource.indexOf(name)) {
  6787. resource.push(name);
  6788. }
  6789. });
  6790. });
  6791. return resource;
  6792. },
  6793. queryState: function(km) {
  6794. return km.getSelectedNode() ? 0 : -1;
  6795. }
  6796. });
  6797. /**
  6798. * @class 资源的覆盖图形
  6799. *
  6800. * 该类为一个资源以指定的颜色渲染一个动态的覆盖图形
  6801. */
  6802. var ResourceOverlay = kity.createClass("ResourceOverlay", {
  6803. base: kity.Group,
  6804. constructor: function() {
  6805. this.callBase();
  6806. var text, rect;
  6807. rect = this.rect = new kity.Rect().setRadius(4);
  6808. text = this.text = new kity.Text().setFontSize(12).setVerticalAlign("middle");
  6809. this.addShapes([ rect, text ]);
  6810. },
  6811. setValue: function(resourceName, color) {
  6812. var paddingX = 8, paddingY = 4, borderRadius = 4;
  6813. var text, box, rect;
  6814. text = this.text;
  6815. if (resourceName == this.lastResourceName) {
  6816. box = this.lastBox;
  6817. } else {
  6818. text.setContent(resourceName);
  6819. box = text.getBoundaryBox();
  6820. this.lastResourceName = resourceName;
  6821. this.lastBox = box;
  6822. }
  6823. text.setX(paddingX).fill(color.dec("l", 70));
  6824. rect = this.rect;
  6825. rect.setPosition(0, box.y - paddingY);
  6826. this.width = Math.round(box.width + paddingX * 2);
  6827. this.height = Math.round(box.height + paddingY * 2);
  6828. rect.setSize(this.width, this.height);
  6829. rect.fill(color);
  6830. }
  6831. });
  6832. /**
  6833. * @class 资源渲染器
  6834. */
  6835. var ResourceRenderer = kity.createClass("ResourceRenderer", {
  6836. base: Renderer,
  6837. create: function(node) {
  6838. this.overlays = [];
  6839. return new kity.Group();
  6840. },
  6841. shouldRender: function(node) {
  6842. return node.getData("resource") && node.getData("resource").length;
  6843. },
  6844. update: function(container, node, box) {
  6845. var spaceRight = node.getStyle("space-right");
  6846. var overlays = this.overlays;
  6847. /* 修复 resource 数组中出现 null 的 bug
  6848. * @Author zhangbobell
  6849. * @date 2016-01-15
  6850. */
  6851. var resource = node.getData("resource").filter(function(ele) {
  6852. return ele !== null;
  6853. });
  6854. if (resource.length === 0) {
  6855. return;
  6856. }
  6857. var minder = node.getMinder();
  6858. var i, overlay, x;
  6859. x = 0;
  6860. for (i = 0; i < resource.length; i++) {
  6861. x += spaceRight;
  6862. overlay = overlays[i];
  6863. if (!overlay) {
  6864. overlay = new ResourceOverlay();
  6865. overlays.push(overlay);
  6866. container.addShape(overlay);
  6867. }
  6868. overlay.setVisible(true);
  6869. overlay.setValue(resource[i], minder.getResourceColor(resource[i]));
  6870. overlay.setTranslate(x, -1);
  6871. x += overlay.width;
  6872. }
  6873. while (overlay = overlays[i++]) overlay.setVisible(false);
  6874. container.setTranslate(box.right, 0);
  6875. return new kity.Box({
  6876. x: box.right,
  6877. y: Math.round(-overlays[0].height / 2),
  6878. width: x,
  6879. height: overlays[0].height
  6880. });
  6881. }
  6882. });
  6883. return {
  6884. commands: {
  6885. resource: ResourceCommand
  6886. },
  6887. renderers: {
  6888. right: ResourceRenderer
  6889. }
  6890. };
  6891. });
  6892. }
  6893. };
  6894. //src/module/select.js
  6895. _p[59] = {
  6896. value: function(require, exports, module) {
  6897. var kity = _p.r(17);
  6898. var utils = _p.r(33);
  6899. var Minder = _p.r(19);
  6900. var MinderNode = _p.r(21);
  6901. var Command = _p.r(9);
  6902. var Module = _p.r(20);
  6903. var Renderer = _p.r(27);
  6904. Module.register("Select", function() {
  6905. var minder = this;
  6906. var rc = minder.getRenderContainer();
  6907. // 在实例上渲染框选矩形、计算框选范围的对象
  6908. var marqueeActivator = function() {
  6909. // 记录选区的开始位置(mousedown的位置)
  6910. var startPosition = null;
  6911. // 选区的图形
  6912. var marqueeShape = new kity.Path();
  6913. // 标记是否已经启动框选状态
  6914. // 并不是 mousedown 发生之后就启动框选状态,而是检测到移动了一定的距离(MARQUEE_MODE_THRESHOLD)之后
  6915. var marqueeMode = false;
  6916. var MARQUEE_MODE_THRESHOLD = 10;
  6917. return {
  6918. selectStart: function(e) {
  6919. // 只接受左键
  6920. if (e.originEvent.button || e.originEvent.altKey) return;
  6921. // 清理不正确状态
  6922. if (startPosition) {
  6923. return this.selectEnd();
  6924. }
  6925. startPosition = e.getPosition(rc).round();
  6926. },
  6927. selectMove: function(e) {
  6928. if (minder.getStatus() == "textedit") {
  6929. return;
  6930. }
  6931. if (!startPosition) return;
  6932. var p1 = startPosition, p2 = e.getPosition(rc);
  6933. // 检测是否要进入选区模式
  6934. if (!marqueeMode) {
  6935. // 距离没达到阈值,退出
  6936. if (kity.Vector.fromPoints(p1, p2).length() < MARQUEE_MODE_THRESHOLD) {
  6937. return;
  6938. }
  6939. // 已经达到阈值,记录下来并且重置选区形状
  6940. marqueeMode = true;
  6941. rc.addShape(marqueeShape);
  6942. marqueeShape.fill(minder.getStyle("marquee-background")).stroke(minder.getStyle("marquee-stroke")).setOpacity(.8).getDrawer().clear();
  6943. }
  6944. var marquee = new kity.Box(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y), selectedNodes = [];
  6945. // 使其犀利
  6946. marquee.left = Math.round(marquee.left);
  6947. marquee.top = Math.round(marquee.top);
  6948. marquee.right = Math.round(marquee.right);
  6949. marquee.bottom = Math.round(marquee.bottom);
  6950. // 选区形状更新
  6951. marqueeShape.getDrawer().pipe(function() {
  6952. this.clear();
  6953. this.moveTo(marquee.left, marquee.top);
  6954. this.lineTo(marquee.right, marquee.top);
  6955. this.lineTo(marquee.right, marquee.bottom);
  6956. this.lineTo(marquee.left, marquee.bottom);
  6957. this.close();
  6958. });
  6959. // 计算选中范围
  6960. minder.getRoot().traverse(function(node) {
  6961. var renderBox = node.getLayoutBox();
  6962. if (!renderBox.intersect(marquee).isEmpty()) {
  6963. selectedNodes.push(node);
  6964. }
  6965. });
  6966. // 应用选中范围
  6967. minder.select(selectedNodes, true);
  6968. // 清除多余的东西
  6969. window.getSelection().removeAllRanges();
  6970. },
  6971. selectEnd: function(e) {
  6972. if (startPosition) {
  6973. startPosition = null;
  6974. }
  6975. if (marqueeMode) {
  6976. marqueeShape.fadeOut(200, "ease", 0, function() {
  6977. if (marqueeShape.remove) marqueeShape.remove();
  6978. });
  6979. marqueeMode = false;
  6980. }
  6981. }
  6982. };
  6983. }();
  6984. var lastDownNode = null, lastDownPosition = null;
  6985. return {
  6986. init: function() {
  6987. window.addEventListener("mouseup", function() {
  6988. marqueeActivator.selectEnd();
  6989. });
  6990. },
  6991. events: {
  6992. mousedown: function(e) {
  6993. var downNode = e.getTargetNode();
  6994. // 没有点中节点:
  6995. // 清除选中状态,并且标记选区开始位置
  6996. if (!downNode) {
  6997. this.removeAllSelectedNodes();
  6998. marqueeActivator.selectStart(e);
  6999. this.setStatus("normal");
  7000. } else if (e.isShortcutKey("Ctrl")) {
  7001. this.toggleSelect(downNode);
  7002. } else if (!downNode.isSelected()) {
  7003. this.select(downNode, true);
  7004. } else if (!this.isSingleSelect()) {
  7005. lastDownNode = downNode;
  7006. lastDownPosition = e.getPosition();
  7007. }
  7008. },
  7009. mousemove: marqueeActivator.selectMove,
  7010. mouseup: function(e) {
  7011. var upNode = e.getTargetNode();
  7012. // 如果 mouseup 发生在 lastDownNode 外,是无需理会的
  7013. if (upNode && upNode == lastDownNode) {
  7014. var upPosition = e.getPosition();
  7015. var movement = kity.Vector.fromPoints(lastDownPosition, upPosition);
  7016. if (movement.length() < 1) this.select(lastDownNode, true);
  7017. lastDownNode = null;
  7018. }
  7019. // 清理一下选择状态
  7020. marqueeActivator.selectEnd(e);
  7021. },
  7022. //全选操作
  7023. "normal.keydown": function(e) {
  7024. if (e.isShortcutKey("ctrl+a")) {
  7025. var selectedNodes = [];
  7026. this.getRoot().traverse(function(node) {
  7027. selectedNodes.push(node);
  7028. });
  7029. this.select(selectedNodes, true);
  7030. e.preventDefault();
  7031. }
  7032. }
  7033. }
  7034. };
  7035. });
  7036. }
  7037. };
  7038. //src/module/style.js
  7039. _p[60] = {
  7040. value: function(require, exports, module) {
  7041. var kity = _p.r(17);
  7042. var utils = _p.r(33);
  7043. var Minder = _p.r(19);
  7044. var MinderNode = _p.r(21);
  7045. var Command = _p.r(9);
  7046. var Module = _p.r(20);
  7047. var Renderer = _p.r(27);
  7048. Module.register("StyleModule", function() {
  7049. var styleNames = [ "font-size", "font-family", "font-weight", "font-style", "background", "color" ];
  7050. var styleClipBoard = null;
  7051. function hasStyle(node) {
  7052. var data = node.getData();
  7053. for (var i = 0; i < styleNames.length; i++) {
  7054. if (styleNames[i] in data) return true;
  7055. }
  7056. }
  7057. return {
  7058. commands: {
  7059. /**
  7060. * @command CopyStyle
  7061. * @description 拷贝选中节点的当前样式,包括字体、字号、粗体、斜体、背景色、字体色
  7062. * @state
  7063. * 0: 当前有选中的节点
  7064. * -1: 当前没有选中的节点
  7065. */
  7066. copystyle: kity.createClass("CopyStyleCommand", {
  7067. base: Command,
  7068. execute: function(minder) {
  7069. var node = minder.getSelectedNode();
  7070. var nodeData = node.getData();
  7071. styleClipBoard = {};
  7072. styleNames.forEach(function(name) {
  7073. if (name in nodeData) styleClipBoard[name] = nodeData[name]; else {
  7074. styleClipBoard[name] = null;
  7075. delete styleClipBoard[name];
  7076. }
  7077. });
  7078. return styleClipBoard;
  7079. },
  7080. queryState: function(minder) {
  7081. var nodes = minder.getSelectedNodes();
  7082. if (nodes.length !== 1) return -1;
  7083. return hasStyle(nodes[0]) ? 0 : -1;
  7084. }
  7085. }),
  7086. /**
  7087. * @command PasteStyle
  7088. * @description 粘贴已拷贝的样式到选中的节点上,包括字体、字号、粗体、斜体、背景色、字体色
  7089. * @state
  7090. * 0: 当前有选中的节点,并且已经有复制的样式
  7091. * -1: 当前没有选中的节点,或者没有复制的样式
  7092. */
  7093. pastestyle: kity.createClass("PastStyleCommand", {
  7094. base: Command,
  7095. execute: function(minder) {
  7096. minder.getSelectedNodes().forEach(function(node) {
  7097. for (var name in styleClipBoard) {
  7098. if (styleClipBoard.hasOwnProperty(name)) node.setData(name, styleClipBoard[name]);
  7099. }
  7100. });
  7101. minder.renderNodeBatch(minder.getSelectedNodes());
  7102. minder.layout(300);
  7103. return styleClipBoard;
  7104. },
  7105. queryState: function(minder) {
  7106. return styleClipBoard && minder.getSelectedNodes().length ? 0 : -1;
  7107. }
  7108. }),
  7109. /**
  7110. * @command ClearStyle
  7111. * @description 移除选中节点的样式,包括字体、字号、粗体、斜体、背景色、字体色
  7112. * @state
  7113. * 0: 当前有选中的节点,并且至少有一个设置了至少一种样式
  7114. * -1: 其它情况
  7115. */
  7116. clearstyle: kity.createClass("ClearStyleCommand", {
  7117. base: Command,
  7118. execute: function(minder) {
  7119. minder.getSelectedNodes().forEach(function(node) {
  7120. styleNames.forEach(function(name) {
  7121. node.setData(name);
  7122. });
  7123. });
  7124. minder.renderNodeBatch(minder.getSelectedNodes());
  7125. minder.layout(300);
  7126. return styleClipBoard;
  7127. },
  7128. queryState: function(minder) {
  7129. var nodes = minder.getSelectedNodes();
  7130. if (!nodes.length) return -1;
  7131. for (var i = 0; i < nodes.length; i++) {
  7132. if (hasStyle(nodes[i])) return 0;
  7133. }
  7134. return -1;
  7135. }
  7136. })
  7137. }
  7138. };
  7139. });
  7140. }
  7141. };
  7142. //src/module/text.js
  7143. _p[61] = {
  7144. value: function(require, exports, module) {
  7145. var kity = _p.r(17);
  7146. var utils = _p.r(33);
  7147. var Minder = _p.r(19);
  7148. var MinderNode = _p.r(21);
  7149. var Command = _p.r(9);
  7150. var Module = _p.r(20);
  7151. var Renderer = _p.r(27);
  7152. /**
  7153. * 针对不同系统、不同浏览器、不同字体做居中兼容性处理
  7154. * 暂时未增加Linux的处理
  7155. */
  7156. var FONT_ADJUST = {
  7157. safari: {
  7158. "微软雅黑,Microsoft YaHei": -.17,
  7159. "楷体,楷体_GB2312,SimKai": -.1,
  7160. "隶书, SimLi": -.1,
  7161. "comic sans ms": -.23,
  7162. "impact,chicago": -.15,
  7163. "times new roman": -.1,
  7164. "arial black,avant garde": -.17,
  7165. default: 0
  7166. },
  7167. ie: {
  7168. 10: {
  7169. "微软雅黑,Microsoft YaHei": -.17,
  7170. "comic sans ms": -.17,
  7171. "impact,chicago": -.08,
  7172. "times new roman": .04,
  7173. "arial black,avant garde": -.17,
  7174. default: -.15
  7175. },
  7176. 11: {
  7177. "微软雅黑,Microsoft YaHei": -.17,
  7178. "arial,helvetica,sans-serif": -.17,
  7179. "comic sans ms": -.17,
  7180. "impact,chicago": -.08,
  7181. "times new roman": .04,
  7182. "sans-serif": -.16,
  7183. "arial black,avant garde": -.17,
  7184. default: -.15
  7185. }
  7186. },
  7187. edge: {
  7188. "微软雅黑,Microsoft YaHei": -.15,
  7189. "arial,helvetica,sans-serif": -.17,
  7190. "comic sans ms": -.17,
  7191. "impact,chicago": -.08,
  7192. "sans-serif": -.16,
  7193. "arial black,avant garde": -.17,
  7194. default: -.15
  7195. },
  7196. sg: {
  7197. "微软雅黑,Microsoft YaHei": -.15,
  7198. "arial,helvetica,sans-serif": -.05,
  7199. "comic sans ms": -.22,
  7200. "impact,chicago": -.16,
  7201. "times new roman": -.03,
  7202. "arial black,avant garde": -.22,
  7203. default: -.15
  7204. },
  7205. chrome: {
  7206. Mac: {
  7207. "andale mono": -.05,
  7208. "comic sans ms": -.3,
  7209. "impact,chicago": -.13,
  7210. "times new roman": -.1,
  7211. "arial black,avant garde": -.17,
  7212. default: 0
  7213. },
  7214. Win: {
  7215. "微软雅黑,Microsoft YaHei": -.15,
  7216. "arial,helvetica,sans-serif": -.02,
  7217. "arial black,avant garde": -.2,
  7218. "comic sans ms": -.2,
  7219. "impact,chicago": -.12,
  7220. "times new roman": -.02,
  7221. default: -.15
  7222. },
  7223. Lux: {
  7224. "andale mono": -.05,
  7225. "comic sans ms": -.3,
  7226. "impact,chicago": -.13,
  7227. "times new roman": -.1,
  7228. "arial black,avant garde": -.17,
  7229. default: 0
  7230. }
  7231. },
  7232. firefox: {
  7233. Mac: {
  7234. "微软雅黑,Microsoft YaHei": -.2,
  7235. "宋体,SimSun": .05,
  7236. "comic sans ms": -.2,
  7237. "impact,chicago": -.15,
  7238. "arial black,avant garde": -.17,
  7239. "times new roman": -.1,
  7240. default: .05
  7241. },
  7242. Win: {
  7243. "微软雅黑,Microsoft YaHei": -.16,
  7244. "andale mono": -.17,
  7245. "arial,helvetica,sans-serif": -.17,
  7246. "comic sans ms": -.22,
  7247. "impact,chicago": -.23,
  7248. "times new roman": -.22,
  7249. "sans-serif": -.22,
  7250. "arial black,avant garde": -.17,
  7251. default: -.16
  7252. },
  7253. Lux: {
  7254. "宋体,SimSun": -.2,
  7255. "微软雅黑,Microsoft YaHei": -.2,
  7256. "黑体, SimHei": -.2,
  7257. "隶书, SimLi": -.2,
  7258. "楷体,楷体_GB2312,SimKai": -.2,
  7259. "andale mono": -.2,
  7260. "arial,helvetica,sans-serif": -.2,
  7261. "comic sans ms": -.2,
  7262. "impact,chicago": -.2,
  7263. "times new roman": -.2,
  7264. "sans-serif": -.2,
  7265. "arial black,avant garde": -.2,
  7266. default: -.16
  7267. }
  7268. }
  7269. };
  7270. var TextRenderer = kity.createClass("TextRenderer", {
  7271. base: Renderer,
  7272. create: function() {
  7273. return new kity.Group().setId(utils.uuid("node_text"));
  7274. },
  7275. update: function(textGroup, node) {
  7276. function getDataOrStyle(name) {
  7277. return node.getData(name) || node.getStyle(name);
  7278. }
  7279. var nodeText = node.getText();
  7280. var textArr = nodeText ? nodeText.split("\n") : [ " " ];
  7281. var lineHeight = node.getStyle("line-height");
  7282. var fontSize = getDataOrStyle("font-size");
  7283. var fontFamily = getDataOrStyle("font-family") || "default";
  7284. var height = lineHeight * fontSize * textArr.length - (lineHeight - 1) * fontSize;
  7285. var yStart = -height / 2;
  7286. var Browser = kity.Browser;
  7287. var adjust;
  7288. if (Browser.chrome || Browser.opera || Browser.bd || Browser.lb === "chrome") {
  7289. adjust = FONT_ADJUST["chrome"][Browser.platform][fontFamily];
  7290. } else if (Browser.gecko) {
  7291. adjust = FONT_ADJUST["firefox"][Browser.platform][fontFamily];
  7292. } else if (Browser.sg) {
  7293. adjust = FONT_ADJUST["sg"][fontFamily];
  7294. } else if (Browser.safari) {
  7295. adjust = FONT_ADJUST["safari"][fontFamily];
  7296. } else if (Browser.ie) {
  7297. adjust = FONT_ADJUST["ie"][Browser.version][fontFamily];
  7298. } else if (Browser.edge) {
  7299. adjust = FONT_ADJUST["edge"][fontFamily];
  7300. } else if (Browser.lb) {
  7301. // 猎豹浏览器的ie内核兼容性模式下
  7302. adjust = .9;
  7303. }
  7304. textGroup.setTranslate(0, (adjust || 0) * fontSize);
  7305. var rBox = new kity.Box(), r = Math.round;
  7306. this.setTextStyle(node, textGroup);
  7307. var textLength = textArr.length;
  7308. var textGroupLength = textGroup.getItems().length;
  7309. var i, ci, textShape, text;
  7310. if (textLength < textGroupLength) {
  7311. for (i = textLength, ci; ci = textGroup.getItem(i); ) {
  7312. textGroup.removeItem(i);
  7313. }
  7314. } else if (textLength > textGroupLength) {
  7315. var growth = textLength - textGroupLength;
  7316. while (growth--) {
  7317. textShape = new kity.Text().setAttr("text-rendering", "inherit");
  7318. if (kity.Browser.ie || kity.Browser.edge) {
  7319. textShape.setVerticalAlign("top");
  7320. } else {
  7321. textShape.setAttr("dominant-baseline", "text-before-edge");
  7322. }
  7323. textGroup.addItem(textShape);
  7324. }
  7325. }
  7326. for (i = 0, text, textShape; text = textArr[i], textShape = textGroup.getItem(i); i++) {
  7327. textShape.setContent(text);
  7328. if (kity.Browser.ie || kity.Browser.edge) {
  7329. textShape.fixPosition();
  7330. }
  7331. }
  7332. this.setTextStyle(node, textGroup);
  7333. var textHash = node.getText() + [ "font-size", "font-name", "font-weight", "font-style" ].map(getDataOrStyle).join("/");
  7334. if (node._currentTextHash == textHash && node._currentTextGroupBox) return node._currentTextGroupBox;
  7335. node._currentTextHash = textHash;
  7336. return function() {
  7337. textGroup.eachItem(function(i, textShape) {
  7338. var y = yStart + i * fontSize * lineHeight;
  7339. textShape.setY(y);
  7340. var bbox = textShape.getBoundaryBox();
  7341. rBox = rBox.merge(new kity.Box(0, y, bbox.height && bbox.width || 1, fontSize));
  7342. });
  7343. var nBox = new kity.Box(r(rBox.x), r(rBox.y), r(rBox.width), r(rBox.height));
  7344. node._currentTextGroupBox = nBox;
  7345. return nBox;
  7346. };
  7347. },
  7348. setTextStyle: function(node, text) {
  7349. var hooks = TextRenderer._styleHooks;
  7350. hooks.forEach(function(hook) {
  7351. hook(node, text);
  7352. });
  7353. }
  7354. });
  7355. var TextCommand = kity.createClass({
  7356. base: Command,
  7357. execute: function(minder, text) {
  7358. var node = minder.getSelectedNode();
  7359. if (node) {
  7360. node.setText(text);
  7361. node.render();
  7362. minder.layout();
  7363. }
  7364. },
  7365. queryState: function(minder) {
  7366. return minder.getSelectedNodes().length == 1 ? 0 : -1;
  7367. },
  7368. queryValue: function(minder) {
  7369. var node = minder.getSelectedNode();
  7370. return node ? node.getText() : null;
  7371. }
  7372. });
  7373. utils.extend(TextRenderer, {
  7374. _styleHooks: [],
  7375. registerStyleHook: function(fn) {
  7376. TextRenderer._styleHooks.push(fn);
  7377. }
  7378. });
  7379. kity.extendClass(MinderNode, {
  7380. getTextGroup: function() {
  7381. return this.getRenderer("TextRenderer").getRenderShape();
  7382. }
  7383. });
  7384. Module.register("text", {
  7385. commands: {
  7386. text: TextCommand
  7387. },
  7388. renderers: {
  7389. center: TextRenderer
  7390. }
  7391. });
  7392. module.exports = TextRenderer;
  7393. }
  7394. };
  7395. //src/module/view.js
  7396. _p[62] = {
  7397. value: function(require, exports, module) {
  7398. var kity = _p.r(17);
  7399. var utils = _p.r(33);
  7400. var Minder = _p.r(19);
  7401. var MinderNode = _p.r(21);
  7402. var Command = _p.r(9);
  7403. var Module = _p.r(20);
  7404. var Renderer = _p.r(27);
  7405. var ViewDragger = kity.createClass("ViewDragger", {
  7406. constructor: function(minder) {
  7407. this._minder = minder;
  7408. this._enabled = false;
  7409. this._bind();
  7410. var me = this;
  7411. this._minder.getViewDragger = function() {
  7412. return me;
  7413. };
  7414. this.setEnabled(false);
  7415. },
  7416. isEnabled: function() {
  7417. return this._enabled;
  7418. },
  7419. setEnabled: function(value) {
  7420. var paper = this._minder.getPaper();
  7421. paper.setStyle("cursor", value ? "pointer" : "default");
  7422. paper.setStyle("cursor", value ? "-webkit-grab" : "default");
  7423. this._enabled = value;
  7424. },
  7425. timeline: function() {
  7426. return this._moveTimeline;
  7427. },
  7428. move: function(offset, duration) {
  7429. var minder = this._minder;
  7430. var targetPosition = this.getMovement().offset(offset);
  7431. this.moveTo(targetPosition, duration);
  7432. },
  7433. moveTo: function(position, duration) {
  7434. if (duration) {
  7435. var dragger = this;
  7436. if (this._moveTimeline) this._moveTimeline.stop();
  7437. this._moveTimeline = this._minder.getRenderContainer().animate(new kity.Animator(this.getMovement(), position, function(target, value) {
  7438. dragger.moveTo(value);
  7439. }), duration, "easeOutCubic").timeline();
  7440. this._moveTimeline.on("finish", function() {
  7441. dragger._moveTimeline = null;
  7442. });
  7443. return this;
  7444. }
  7445. this._minder.getRenderContainer().setTranslate(position.round());
  7446. this._minder.fire("viewchange");
  7447. },
  7448. getMovement: function() {
  7449. var translate = this._minder.getRenderContainer().transform.translate;
  7450. return translate ? translate[0] : new kity.Point();
  7451. },
  7452. getView: function() {
  7453. var minder = this._minder;
  7454. var c = minder._lastClientSize || {
  7455. width: minder.getRenderTarget().clientWidth,
  7456. height: minder.getRenderTarget().clientHeight
  7457. };
  7458. var m = this.getMovement();
  7459. var box = new kity.Box(0, 0, c.width, c.height);
  7460. var viewMatrix = minder.getPaper().getViewPortMatrix();
  7461. return viewMatrix.inverse().translate(-m.x, -m.y).transformBox(box);
  7462. },
  7463. _bind: function() {
  7464. var dragger = this, isTempDrag = false, lastPosition = null, currentPosition = null;
  7465. function dragEnd(e) {
  7466. if (!lastPosition) return;
  7467. lastPosition = null;
  7468. e.stopPropagation();
  7469. // 临时拖动需要还原状态
  7470. if (isTempDrag) {
  7471. dragger.setEnabled(false);
  7472. isTempDrag = false;
  7473. if (dragger._minder.getStatus() == "hand") dragger._minder.rollbackStatus();
  7474. }
  7475. var paper = dragger._minder.getPaper();
  7476. paper.setStyle("cursor", dragger._minder.getStatus() == "hand" ? "-webkit-grab" : "default");
  7477. dragger._minder.fire("viewchanged");
  7478. }
  7479. this._minder.on("normal.mousedown normal.touchstart " + "inputready.mousedown inputready.touchstart " + "readonly.mousedown readonly.touchstart", function(e) {
  7480. if (e.originEvent.button == 2) {
  7481. e.originEvent.preventDefault();
  7482. }
  7483. // 点击未选中的根节点临时开启
  7484. if (e.getTargetNode() == this.getRoot() || e.originEvent.button == 2 || e.originEvent.altKey) {
  7485. lastPosition = e.getPosition("view");
  7486. isTempDrag = true;
  7487. }
  7488. }).on("normal.mousemove normal.touchmove " + "readonly.mousemove readonly.touchmove " + "inputready.mousemove inputready.touchmove", function(e) {
  7489. if (e.type == "touchmove") {
  7490. e.preventDefault();
  7491. }
  7492. if (!isTempDrag) return;
  7493. var offset = kity.Vector.fromPoints(lastPosition, e.getPosition("view"));
  7494. if (offset.length() > 10) {
  7495. this.setStatus("hand", true);
  7496. var paper = dragger._minder.getPaper();
  7497. paper.setStyle("cursor", "-webkit-grabbing");
  7498. }
  7499. }).on("hand.beforemousedown hand.beforetouchstart", function(e) {
  7500. // 已经被用户打开拖放模式
  7501. if (dragger.isEnabled()) {
  7502. lastPosition = e.getPosition("view");
  7503. e.stopPropagation();
  7504. var paper = dragger._minder.getPaper();
  7505. paper.setStyle("cursor", "-webkit-grabbing");
  7506. }
  7507. }).on("hand.beforemousemove hand.beforetouchmove", function(e) {
  7508. if (lastPosition) {
  7509. currentPosition = e.getPosition("view");
  7510. // 当前偏移加上历史偏移
  7511. var offset = kity.Vector.fromPoints(lastPosition, currentPosition);
  7512. dragger.move(offset);
  7513. e.stopPropagation();
  7514. e.preventDefault();
  7515. e.originEvent.preventDefault();
  7516. lastPosition = currentPosition;
  7517. }
  7518. }).on("mouseup touchend", dragEnd);
  7519. window.addEventListener("mouseup", dragEnd);
  7520. this._minder.on("contextmenu", function(e) {
  7521. e.preventDefault();
  7522. });
  7523. }
  7524. });
  7525. Module.register("View", function() {
  7526. var km = this;
  7527. /**
  7528. * @command Hand
  7529. * @description 切换抓手状态,抓手状态下,鼠标拖动将拖动视野,而不是创建选区
  7530. * @state
  7531. * 0: 当前不是抓手状态
  7532. * 1: 当前是抓手状态
  7533. */
  7534. var ToggleHandCommand = kity.createClass("ToggleHandCommand", {
  7535. base: Command,
  7536. execute: function(minder) {
  7537. if (minder.getStatus() != "hand") {
  7538. minder.setStatus("hand", true);
  7539. } else {
  7540. minder.rollbackStatus();
  7541. }
  7542. this.setContentChanged(false);
  7543. },
  7544. queryState: function(minder) {
  7545. return minder.getStatus() == "hand" ? 1 : 0;
  7546. },
  7547. enableReadOnly: true
  7548. });
  7549. /**
  7550. * @command Camera
  7551. * @description 设置当前视野的中心位置到某个节点上
  7552. * @param {kityminder.MinderNode} focusNode 要定位的节点
  7553. * @param {number} duration 设置视野移动的动画时长(单位 ms),设置为 0 不使用动画
  7554. * @state
  7555. * 0: 始终可用
  7556. */
  7557. var CameraCommand = kity.createClass("CameraCommand", {
  7558. base: Command,
  7559. execute: function(km, focusNode) {
  7560. focusNode = focusNode || km.getRoot();
  7561. var viewport = km.getPaper().getViewPort();
  7562. var offset = focusNode.getRenderContainer().getRenderBox("view");
  7563. var dx = viewport.center.x - offset.x - offset.width / 2, dy = viewport.center.y - offset.y;
  7564. var dragger = km._viewDragger;
  7565. var duration = km.getOption("viewAnimationDuration");
  7566. dragger.move(new kity.Point(dx, dy), duration);
  7567. this.setContentChanged(false);
  7568. },
  7569. enableReadOnly: true
  7570. });
  7571. /**
  7572. * @command Move
  7573. * @description 指定方向移动当前视野
  7574. * @param {string} dir 移动方向
  7575. * 取值为 'left',视野向左移动一半
  7576. * 取值为 'right',视野向右移动一半
  7577. * 取值为 'up',视野向上移动一半
  7578. * 取值为 'down',视野向下移动一半
  7579. * @param {number} duration 视野移动的动画时长(单位 ms),设置为 0 不使用动画
  7580. * @state
  7581. * 0: 始终可用
  7582. */
  7583. var MoveCommand = kity.createClass("MoveCommand", {
  7584. base: Command,
  7585. execute: function(km, dir) {
  7586. var dragger = km._viewDragger;
  7587. var size = km._lastClientSize;
  7588. var duration = km.getOption("viewAnimationDuration");
  7589. switch (dir) {
  7590. case "up":
  7591. dragger.move(new kity.Point(0, size.height / 2), duration);
  7592. break;
  7593. case "down":
  7594. dragger.move(new kity.Point(0, -size.height / 2), duration);
  7595. break;
  7596. case "left":
  7597. dragger.move(new kity.Point(size.width / 2, 0), duration);
  7598. break;
  7599. case "right":
  7600. dragger.move(new kity.Point(-size.width / 2, 0), duration);
  7601. break;
  7602. }
  7603. },
  7604. enableReadOnly: true
  7605. });
  7606. return {
  7607. init: function() {
  7608. this._viewDragger = new ViewDragger(this);
  7609. },
  7610. commands: {
  7611. hand: ToggleHandCommand,
  7612. camera: CameraCommand,
  7613. move: MoveCommand
  7614. },
  7615. events: {
  7616. statuschange: function(e) {
  7617. this._viewDragger.setEnabled(e.currentStatus == "hand");
  7618. },
  7619. mousewheel: function(e) {
  7620. var dx, dy;
  7621. e = e.originEvent;
  7622. if (e.ctrlKey || e.shiftKey) return;
  7623. if ("wheelDeltaX" in e) {
  7624. dx = e.wheelDeltaX || 0;
  7625. dy = e.wheelDeltaY || 0;
  7626. } else {
  7627. dx = 0;
  7628. dy = e.wheelDelta;
  7629. }
  7630. this._viewDragger.move({
  7631. x: dx / 2.5,
  7632. y: dy / 2.5
  7633. });
  7634. var me = this;
  7635. clearTimeout(this._mousewheeltimer);
  7636. this._mousewheeltimer = setTimeout(function() {
  7637. me.fire("viewchanged");
  7638. }, 100);
  7639. e.preventDefault();
  7640. },
  7641. "normal.dblclick readonly.dblclick": function(e) {
  7642. if (e.kityEvent.targetShape instanceof kity.Paper) {
  7643. this.execCommand("camera", this.getRoot(), 800);
  7644. }
  7645. },
  7646. "paperrender finishInitHook": function() {
  7647. if (!this.getRenderTarget()) {
  7648. return;
  7649. }
  7650. this.execCommand("camera", null, 0);
  7651. this._lastClientSize = {
  7652. width: this.getRenderTarget().clientWidth,
  7653. height: this.getRenderTarget().clientHeight
  7654. };
  7655. },
  7656. resize: function(e) {
  7657. var a = {
  7658. width: this.getRenderTarget().clientWidth,
  7659. height: this.getRenderTarget().clientHeight
  7660. }, b = this._lastClientSize;
  7661. this._viewDragger.move(new kity.Point((a.width - b.width) / 2 | 0, (a.height - b.height) / 2 | 0));
  7662. this._lastClientSize = a;
  7663. },
  7664. "selectionchange layoutallfinish": function(e) {
  7665. var selected = this.getSelectedNode();
  7666. var minder = this;
  7667. /*
  7668. * Added by zhangbobell 2015.9.9
  7669. * windows 10 的 edge 浏览器在全部动画停止后,优先级图标不显示 text,
  7670. * 因此再次触发一次 render 事件,让浏览器重绘
  7671. * */
  7672. if (kity.Browser.edge) {
  7673. this.fire("paperrender");
  7674. }
  7675. if (!selected) return;
  7676. var dragger = this._viewDragger;
  7677. var timeline = dragger.timeline();
  7678. /*
  7679. * Added by zhangbobell 2015.09.25
  7680. * 如果之前有动画,那么就先暂时返回,等之前动画结束之后再次执行本函数
  7681. * 以防止 view 动画变动了位置,导致本函数执行的时候位置计算不对
  7682. *
  7683. * fixed bug : 初始化的时候中心节点位置不固定(有的时候在左上角,有的时候在中心)
  7684. * */
  7685. if (timeline) {
  7686. timeline.on("finish", function() {
  7687. minder.fire("selectionchange");
  7688. });
  7689. return;
  7690. }
  7691. var view = dragger.getView();
  7692. var focus = selected.getLayoutBox();
  7693. var space = 50;
  7694. var dx = 0, dy = 0;
  7695. if (focus.right > view.right) {
  7696. dx += view.right - focus.right - space;
  7697. } else if (focus.left < view.left) {
  7698. dx += view.left - focus.left + space;
  7699. }
  7700. if (focus.bottom > view.bottom) {
  7701. dy += view.bottom - focus.bottom - space;
  7702. }
  7703. if (focus.top < view.top) {
  7704. dy += view.top - focus.top + space;
  7705. }
  7706. if (dx || dy) dragger.move(new kity.Point(dx, dy), 100);
  7707. }
  7708. }
  7709. };
  7710. });
  7711. }
  7712. };
  7713. //src/module/zoom.js
  7714. _p[63] = {
  7715. value: function(require, exports, module) {
  7716. var kity = _p.r(17);
  7717. var utils = _p.r(33);
  7718. var Minder = _p.r(19);
  7719. var MinderNode = _p.r(21);
  7720. var Command = _p.r(9);
  7721. var Module = _p.r(20);
  7722. var Renderer = _p.r(27);
  7723. Module.register("Zoom", function() {
  7724. var me = this;
  7725. var timeline;
  7726. function setTextRendering() {
  7727. var value = me._zoomValue >= 100 ? "optimize-speed" : "geometricPrecision";
  7728. me.getRenderContainer().setAttr("text-rendering", value);
  7729. }
  7730. function fixPaperCTM(paper) {
  7731. var node = paper.shapeNode;
  7732. var ctm = node.getCTM();
  7733. var matrix = new kity.Matrix(ctm.a, ctm.b, ctm.c, ctm.d, (ctm.e | 0) + .5, (ctm.f | 0) + .5);
  7734. node.setAttribute("transform", "matrix(" + matrix.toString() + ")");
  7735. }
  7736. kity.extendClass(Minder, {
  7737. zoom: function(value) {
  7738. var paper = this.getPaper();
  7739. var viewport = paper.getViewPort();
  7740. viewport.zoom = value / 100;
  7741. viewport.center = {
  7742. x: viewport.center.x,
  7743. y: viewport.center.y
  7744. };
  7745. paper.setViewPort(viewport);
  7746. if (value == 100) fixPaperCTM(paper);
  7747. },
  7748. getZoomValue: function() {
  7749. return this._zoomValue;
  7750. }
  7751. });
  7752. function zoomMinder(minder, value) {
  7753. var paper = minder.getPaper();
  7754. var viewport = paper.getViewPort();
  7755. if (!value) return;
  7756. setTextRendering();
  7757. var duration = minder.getOption("zoomAnimationDuration");
  7758. if (minder.getRoot().getComplex() > 200 || !duration) {
  7759. minder._zoomValue = value;
  7760. minder.zoom(value);
  7761. minder.fire("viewchange");
  7762. } else {
  7763. var animator = new kity.Animator({
  7764. beginValue: minder._zoomValue,
  7765. finishValue: value,
  7766. setter: function(target, value) {
  7767. target.zoom(value);
  7768. }
  7769. });
  7770. minder._zoomValue = value;
  7771. if (timeline) {
  7772. timeline.pause();
  7773. }
  7774. timeline = animator.start(minder, duration, "easeInOutSine");
  7775. timeline.on("finish", function() {
  7776. minder.fire("viewchange");
  7777. });
  7778. }
  7779. minder.fire("zoom", {
  7780. zoom: value
  7781. });
  7782. }
  7783. /**
  7784. * @command Zoom
  7785. * @description 缩放当前的视野到一定的比例(百分比)
  7786. * @param {number} value 设置的比例,取值 100 则为原尺寸
  7787. * @state
  7788. * 0: 始终可用
  7789. */
  7790. var ZoomCommand = kity.createClass("Zoom", {
  7791. base: Command,
  7792. execute: zoomMinder,
  7793. queryValue: function(minder) {
  7794. return minder._zoomValue;
  7795. }
  7796. });
  7797. /**
  7798. * @command ZoomIn
  7799. * @description 放大当前的视野到下一个比例等级(百分比)
  7800. * @shortcut =
  7801. * @state
  7802. * 0: 如果当前脑图的配置中还有下一个比例等级
  7803. * -1: 其它情况
  7804. */
  7805. var ZoomInCommand = kity.createClass("ZoomInCommand", {
  7806. base: Command,
  7807. execute: function(minder) {
  7808. zoomMinder(minder, this.nextValue(minder));
  7809. },
  7810. queryState: function(minder) {
  7811. return +!this.nextValue(minder);
  7812. },
  7813. nextValue: function(minder) {
  7814. var stack = minder.getOption("zoom"), i;
  7815. for (i = 0; i < stack.length; i++) {
  7816. if (stack[i] > minder._zoomValue) return stack[i];
  7817. }
  7818. return 0;
  7819. },
  7820. enableReadOnly: true
  7821. });
  7822. /**
  7823. * @command ZoomOut
  7824. * @description 缩小当前的视野到上一个比例等级(百分比)
  7825. * @shortcut -
  7826. * @state
  7827. * 0: 如果当前脑图的配置中还有上一个比例等级
  7828. * -1: 其它情况
  7829. */
  7830. var ZoomOutCommand = kity.createClass("ZoomOutCommand", {
  7831. base: Command,
  7832. execute: function(minder) {
  7833. zoomMinder(minder, this.nextValue(minder));
  7834. },
  7835. queryState: function(minder) {
  7836. return +!this.nextValue(minder);
  7837. },
  7838. nextValue: function(minder) {
  7839. var stack = minder.getOption("zoom"), i;
  7840. for (i = stack.length - 1; i >= 0; i--) {
  7841. if (stack[i] < minder._zoomValue) return stack[i];
  7842. }
  7843. return 0;
  7844. },
  7845. enableReadOnly: true
  7846. });
  7847. return {
  7848. init: function() {
  7849. this._zoomValue = 100;
  7850. this.setDefaultOptions({
  7851. zoom: [ 10, 20, 50, 100, 200 ]
  7852. });
  7853. setTextRendering();
  7854. },
  7855. commands: {
  7856. zoomin: ZoomInCommand,
  7857. zoomout: ZoomOutCommand,
  7858. zoom: ZoomCommand
  7859. },
  7860. events: {
  7861. "normal.mousewheel readonly.mousewheel": function(e) {
  7862. if (!e.originEvent.ctrlKey && !e.originEvent.metaKey) return;
  7863. var delta = e.originEvent.wheelDelta;
  7864. var me = this;
  7865. // 稀释
  7866. if (Math.abs(delta) > 100) {
  7867. clearTimeout(this._wheelZoomTimeout);
  7868. } else {
  7869. return;
  7870. }
  7871. this._wheelZoomTimeout = setTimeout(function() {
  7872. var value;
  7873. var lastValue = me.getPaper()._zoom || 1;
  7874. if (delta > 0) {
  7875. me.execCommand("zoomin");
  7876. } else if (delta < 0) {
  7877. me.execCommand("zoomout");
  7878. }
  7879. }, 100);
  7880. e.originEvent.preventDefault();
  7881. }
  7882. },
  7883. commandShortcutKeys: {
  7884. zoomin: "ctrl+=",
  7885. zoomout: "ctrl+-"
  7886. }
  7887. };
  7888. });
  7889. }
  7890. };
  7891. //src/protocol/json.js
  7892. _p[64] = {
  7893. value: function(require, exports, module) {
  7894. var data = _p.r(12);
  7895. data.registerProtocol("json", module.exports = {
  7896. fileDescription: "KityMinder 格式",
  7897. fileExtension: ".km",
  7898. dataType: "text",
  7899. mineType: "application/json",
  7900. encode: function(json) {
  7901. return JSON.stringify(json);
  7902. },
  7903. decode: function(local) {
  7904. return JSON.parse(local);
  7905. }
  7906. });
  7907. }
  7908. };
  7909. //src/protocol/markdown.js
  7910. _p[65] = {
  7911. value: function(require, exports, module) {
  7912. var data = _p.r(12);
  7913. var LINE_ENDING_SPLITER = /\r\n|\r|\n/;
  7914. var EMPTY_LINE = "";
  7915. var NOTE_MARK_START = "\x3c!--Note--\x3e";
  7916. var NOTE_MARK_CLOSE = "\x3c!--/Note--\x3e";
  7917. function encode(json) {
  7918. return _build(json, 1).join("\n");
  7919. }
  7920. function _build(node, level) {
  7921. var lines = [];
  7922. level = level || 1;
  7923. var sharps = _generateHeaderSharp(level);
  7924. lines.push(sharps + " " + node.data.text);
  7925. lines.push(EMPTY_LINE);
  7926. var note = node.data.note;
  7927. if (note) {
  7928. var hasSharp = /^#/.test(note);
  7929. if (hasSharp) {
  7930. lines.push(NOTE_MARK_START);
  7931. note = note.replace(/^#+/gm, function($0) {
  7932. return sharps + $0;
  7933. });
  7934. }
  7935. lines.push(note);
  7936. if (hasSharp) {
  7937. lines.push(NOTE_MARK_CLOSE);
  7938. }
  7939. lines.push(EMPTY_LINE);
  7940. }
  7941. if (node.children) node.children.forEach(function(child) {
  7942. lines = lines.concat(_build(child, level + 1));
  7943. });
  7944. return lines;
  7945. }
  7946. function _generateHeaderSharp(level) {
  7947. var sharps = "";
  7948. while (level--) sharps += "#";
  7949. return sharps;
  7950. }
  7951. function decode(markdown) {
  7952. var json, parentMap = {}, lines, line, lineInfo, level, node, parent, noteProgress, codeBlock;
  7953. // 一级标题转换 `{title}\n===` => `# {title}`
  7954. markdown = markdown.replace(/^(.+)\n={3,}/, function($0, $1) {
  7955. return "# " + $1;
  7956. });
  7957. lines = markdown.split(LINE_ENDING_SPLITER);
  7958. // 按行分析
  7959. for (var i = 0; i < lines.length; i++) {
  7960. line = lines[i];
  7961. lineInfo = _resolveLine(line);
  7962. // 备注标记处理
  7963. if (lineInfo.noteClose) {
  7964. noteProgress = false;
  7965. continue;
  7966. } else if (lineInfo.noteStart) {
  7967. noteProgress = true;
  7968. continue;
  7969. }
  7970. // 代码块处理
  7971. codeBlock = lineInfo.codeBlock ? !codeBlock : codeBlock;
  7972. // 备注条件:备注标签中,非标题定义,或标题越位
  7973. if (noteProgress || codeBlock || !lineInfo.level || lineInfo.level > level + 1) {
  7974. if (node) _pushNote(node, line);
  7975. continue;
  7976. }
  7977. // 标题处理
  7978. level = lineInfo.level;
  7979. node = _initNode(lineInfo.content, parentMap[level - 1]);
  7980. parentMap[level] = node;
  7981. }
  7982. _cleanUp(parentMap[1]);
  7983. return parentMap[1];
  7984. }
  7985. function _initNode(text, parent) {
  7986. var node = {
  7987. data: {
  7988. text: text,
  7989. note: ""
  7990. }
  7991. };
  7992. if (parent) {
  7993. if (parent.children) parent.children.push(node); else parent.children = [ node ];
  7994. }
  7995. return node;
  7996. }
  7997. function _pushNote(node, line) {
  7998. node.data.note += line + "\n";
  7999. }
  8000. function _isEmpty(line) {
  8001. return !/\S/.test(line);
  8002. }
  8003. function _resolveLine(line) {
  8004. var match = /^(#+)?\s*(.*)$/.exec(line);
  8005. return {
  8006. level: match[1] && match[1].length || null,
  8007. content: match[2],
  8008. noteStart: line == NOTE_MARK_START,
  8009. noteClose: line == NOTE_MARK_CLOSE,
  8010. codeBlock: /^\s*```/.test(line)
  8011. };
  8012. }
  8013. function _cleanUp(node) {
  8014. if (!/\S/.test(node.data.note)) {
  8015. node.data.note = null;
  8016. delete node.data.note;
  8017. } else {
  8018. var notes = node.data.note.split("\n");
  8019. while (notes.length && !/\S/.test(notes[0])) notes.shift();
  8020. while (notes.length && !/\S/.test(notes[notes.length - 1])) notes.pop();
  8021. node.data.note = notes.join("\n");
  8022. }
  8023. if (node.children) node.children.forEach(_cleanUp);
  8024. }
  8025. data.registerProtocol("markdown", module.exports = {
  8026. fileDescription: "Markdown/GFM 格式",
  8027. fileExtension: ".md",
  8028. mineType: "text/markdown",
  8029. dataType: "text",
  8030. encode: function(json) {
  8031. return encode(json.root);
  8032. },
  8033. decode: function(markdown) {
  8034. return decode(markdown);
  8035. }
  8036. });
  8037. }
  8038. };
  8039. //src/protocol/png.js
  8040. _p[66] = {
  8041. value: function(require, exports, module) {
  8042. var kity = _p.r(17);
  8043. var data = _p.r(12);
  8044. var Promise = _p.r(25);
  8045. var DomURL = window.URL || window.webkitURL || window;
  8046. function loadImage(info, callback) {
  8047. return new Promise(function(resolve, reject) {
  8048. var image = document.createElement("img");
  8049. image.onload = function() {
  8050. resolve({
  8051. element: this,
  8052. x: info.x,
  8053. y: info.y,
  8054. width: info.width,
  8055. height: info.height
  8056. });
  8057. };
  8058. image.onerror = function(err) {
  8059. reject(err);
  8060. };
  8061. image.crossOrigin = "anonymous";
  8062. image.src = info.url;
  8063. });
  8064. }
  8065. /**
  8066. * xhrLoadImage: 通过 xhr 加载保存在 BOS 上的图片
  8067. * @note: BOS 上的 CORS 策略是取 headers 里面的 Origin 字段进行判断
  8068. * 而通过 image 的 src 的方式是无法传递 origin 的,因此需要通过 xhr 进行
  8069. */
  8070. function xhrLoadImage(info, callback) {
  8071. return Promise(function(resolve, reject) {
  8072. var xmlHttp = new XMLHttpRequest();
  8073. xmlHttp.open("GET", info.url + "?_=" + Date.now(), true);
  8074. xmlHttp.responseType = "blob";
  8075. xmlHttp.onreadystatechange = function() {
  8076. if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
  8077. var blob = xmlHttp.response;
  8078. var image = document.createElement("img");
  8079. image.src = DomURL.createObjectURL(blob);
  8080. image.onload = function() {
  8081. DomURL.revokeObjectURL(image.src);
  8082. resolve({
  8083. element: image,
  8084. x: info.x,
  8085. y: info.y,
  8086. width: info.width,
  8087. height: info.height
  8088. });
  8089. };
  8090. }
  8091. };
  8092. xmlHttp.send();
  8093. });
  8094. }
  8095. function getSVGInfo(minder) {
  8096. var paper = minder.getPaper(), paperTransform, domContainer = paper.container, svgXml, svgContainer, svgDom, renderContainer = minder.getRenderContainer(), renderBox = renderContainer.getRenderBox(), width = renderBox.width + 1, height = renderBox.height + 1, blob, svgUrl, img;
  8097. // 保存原始变换,并且移动到合适的位置
  8098. paperTransform = paper.shapeNode.getAttribute("transform");
  8099. paper.shapeNode.setAttribute("transform", "translate(0.5, 0.5)");
  8100. renderContainer.translate(-renderBox.x, -renderBox.y);
  8101. // 获取当前的 XML 代码
  8102. svgXml = paper.container.innerHTML;
  8103. // 回复原始变换及位置
  8104. renderContainer.translate(renderBox.x, renderBox.y);
  8105. paper.shapeNode.setAttribute("transform", paperTransform);
  8106. // 过滤内容
  8107. svgContainer = document.createElement("div");
  8108. svgContainer.innerHTML = svgXml;
  8109. svgDom = svgContainer.querySelector("svg");
  8110. svgDom.setAttribute("width", renderBox.width + 1);
  8111. svgDom.setAttribute("height", renderBox.height + 1);
  8112. svgDom.setAttribute("style", 'font-family: Arial, "Microsoft Yahei","Heiti SC";');
  8113. svgContainer = document.createElement("div");
  8114. svgContainer.appendChild(svgDom);
  8115. svgXml = svgContainer.innerHTML;
  8116. // Dummy IE
  8117. svgXml = svgXml.replace(' xmlns="http://www.w3.org/2000/svg" ' + 'xmlns:NS1="" NS1:ns1:xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:NS2="" NS2:xmlns:ns1=""', "");
  8118. // svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined ,含有控制字符触发Load Image 会触发报错
  8119. svgXml = svgXml.replace(/&nbsp;|[\x00-\x1F\x7F-\x9F]/g, "");
  8120. // fix title issue in safari
  8121. // @ http://stackoverflow.com/questions/30273775/namespace-prefix-ns1-for-href-on-tagelement-is-not-defined-setattributens
  8122. svgXml = svgXml.replace(/NS\d+:title/gi, "xlink:title");
  8123. blob = new Blob([ svgXml ], {
  8124. type: "image/svg+xml"
  8125. });
  8126. svgUrl = DomURL.createObjectURL(blob);
  8127. //svgUrl = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgXml);
  8128. var imagesInfo = [];
  8129. // 遍历取出图片信息
  8130. traverse(minder.getRoot());
  8131. function traverse(node) {
  8132. var nodeData = node.data;
  8133. if (nodeData.image) {
  8134. minder.renderNode(node);
  8135. var nodeData = node.data;
  8136. var imageUrl = nodeData.image;
  8137. var imageSize = nodeData.imageSize;
  8138. var imageRenderBox = node.getRenderBox("ImageRenderer", minder.getRenderContainer());
  8139. var imageInfo = {
  8140. url: imageUrl,
  8141. width: imageSize.width,
  8142. height: imageSize.height,
  8143. x: -renderContainer.getBoundaryBox().x + imageRenderBox.x,
  8144. y: -renderContainer.getBoundaryBox().y + imageRenderBox.y
  8145. };
  8146. imagesInfo.push(imageInfo);
  8147. }
  8148. // 若节点折叠,则直接返回
  8149. if (nodeData.expandState === "collapse") {
  8150. return;
  8151. }
  8152. var children = node.getChildren();
  8153. for (var i = 0; i < children.length; i++) {
  8154. traverse(children[i]);
  8155. }
  8156. }
  8157. return {
  8158. width: width,
  8159. height: height,
  8160. dataUrl: svgUrl,
  8161. xml: svgXml,
  8162. imagesInfo: imagesInfo
  8163. };
  8164. }
  8165. function encode(json, minder, option) {
  8166. var resultCallback;
  8167. /* 绘制 PNG 的画布及上下文 */
  8168. var canvas = document.createElement("canvas");
  8169. var ctx = canvas.getContext("2d");
  8170. /* 尝试获取背景图片 URL 或背景颜色 */
  8171. var bgDeclare = minder.getStyle("background").toString();
  8172. var bgUrl = /url\(\"(.+)\"\)/.exec(bgDeclare);
  8173. var bgColor = kity.Color.parse(bgDeclare);
  8174. /* 获取 SVG 文件内容 */
  8175. var svgInfo = getSVGInfo(minder);
  8176. var width = option && option.width && option.width > svgInfo.width ? option.width : svgInfo.width;
  8177. var height = option && option.height && option.height > svgInfo.height ? option.height : svgInfo.height;
  8178. var offsetX = option && option.width && option.width > svgInfo.width ? (option.width - svgInfo.width) / 2 : 0;
  8179. var offsetY = option && option.height && option.height > svgInfo.height ? (option.height - svgInfo.height) / 2 : 0;
  8180. var svgDataUrl = svgInfo.dataUrl;
  8181. var imagesInfo = svgInfo.imagesInfo;
  8182. /* 画布的填充大小 */
  8183. var padding = 20;
  8184. canvas.width = width + padding * 2;
  8185. canvas.height = height + padding * 2;
  8186. function fillBackground(ctx, style) {
  8187. ctx.save();
  8188. ctx.fillStyle = style;
  8189. ctx.fillRect(0, 0, canvas.width, canvas.height);
  8190. ctx.restore();
  8191. }
  8192. function drawImage(ctx, image, x, y, width, height) {
  8193. if (width && height) {
  8194. ctx.drawImage(image, x + padding, y + padding, width, height);
  8195. } else {
  8196. ctx.drawImage(image, x + padding, y + padding);
  8197. }
  8198. }
  8199. function generateDataUrl(canvas) {
  8200. return canvas.toDataURL("image/png");
  8201. }
  8202. // 加载节点上的图片
  8203. function loadImages(imagesInfo) {
  8204. var imagePromises = imagesInfo.map(function(imageInfo) {
  8205. return xhrLoadImage(imageInfo);
  8206. });
  8207. return Promise.all(imagePromises);
  8208. }
  8209. function drawSVG() {
  8210. var svgData = {
  8211. url: svgDataUrl
  8212. };
  8213. return loadImage(svgData).then(function($image) {
  8214. drawImage(ctx, $image.element, offsetX, offsetY, $image.width, $image.height);
  8215. return loadImages(imagesInfo);
  8216. }).then(function($images) {
  8217. for (var i = 0; i < $images.length; i++) {
  8218. drawImage(ctx, $images[i].element, $images[i].x + offsetX, $images[i].y + offsetY, $images[i].width, $images[i].height);
  8219. }
  8220. DomURL.revokeObjectURL(svgDataUrl);
  8221. document.body.appendChild(canvas);
  8222. var pngBase64 = generateDataUrl(canvas);
  8223. document.body.removeChild(canvas);
  8224. return pngBase64;
  8225. }, function(err) {
  8226. // 这里处理 reject,出错基本上是因为跨域,
  8227. // 出错后依然导出,只不过没有图片。
  8228. alert("脑图的节点中包含跨域图片,导出的 png 中节点图片不显示,你可以替换掉这些跨域的图片并重试。");
  8229. DomURL.revokeObjectURL(svgDataUrl);
  8230. document.body.appendChild(canvas);
  8231. var pngBase64 = generateDataUrl(canvas);
  8232. document.body.removeChild(canvas);
  8233. return pngBase64;
  8234. });
  8235. }
  8236. if (bgUrl) {
  8237. var bgInfo = {
  8238. url: bgUrl[1]
  8239. };
  8240. return loadImage(bgInfo).then(function($image) {
  8241. fillBackground(ctx, ctx.createPattern($image.element, "repeat"));
  8242. return drawSVG();
  8243. });
  8244. } else {
  8245. fillBackground(ctx, bgColor.toString());
  8246. return drawSVG();
  8247. }
  8248. }
  8249. data.registerProtocol("png", module.exports = {
  8250. fileDescription: "PNG 图片",
  8251. fileExtension: ".png",
  8252. mineType: "image/png",
  8253. dataType: "base64",
  8254. encode: encode
  8255. });
  8256. }
  8257. };
  8258. //src/protocol/svg.js
  8259. _p[67] = {
  8260. value: function(require, exports, module) {
  8261. var data = _p.r(12);
  8262. /**
  8263. * 导出svg时删除全部svg元素中的transform
  8264. * @auth Naixor
  8265. * @method removeTransform
  8266. * @param {[type]} svgDom [description]
  8267. * @return {[type]} [description]
  8268. */
  8269. function cleanSVG(svgDom, x, y) {
  8270. function getTransformToElement(target, source) {
  8271. var matrix;
  8272. try {
  8273. matrix = source.getScreenCTM().inverse();
  8274. } catch (e) {
  8275. throw new Error("Can not inverse source element' ctm.");
  8276. }
  8277. return matrix.multiply(target.getScreenCTM());
  8278. }
  8279. function dealWithPath(d, dealWithPattern) {
  8280. if (!(dealWithPattern instanceof Function)) {
  8281. dealWithPattern = function() {};
  8282. }
  8283. var strArr = [], pattern = [], cache = [];
  8284. for (var i = 0, l = d.length; i < l; i++) {
  8285. switch (d[i]) {
  8286. case "M":
  8287. case "L":
  8288. case "T":
  8289. case "S":
  8290. case "A":
  8291. case "C":
  8292. case "H":
  8293. case "V":
  8294. case "Q":
  8295. {
  8296. if (cache.length) {
  8297. pattern.push(cache.join(""));
  8298. cache = [];
  8299. }
  8300. // 脑图的path格式真奇怪...偶尔就给我蹦出来一个"..V123 C..", 那空格几个意思 - -
  8301. if (pattern[pattern.length - 1] === ",") {
  8302. pattern.pop();
  8303. }
  8304. if (pattern.length) {
  8305. dealWithPattern(pattern);
  8306. strArr.push(pattern.join(""));
  8307. pattern = [];
  8308. }
  8309. pattern.push(d[i]);
  8310. break;
  8311. }
  8312. case "Z":
  8313. case "z":
  8314. {
  8315. pattern.push(cache.join(""), d[i]);
  8316. dealWithPattern(pattern);
  8317. strArr.push(pattern.join(""));
  8318. cache = [];
  8319. pattern = [];
  8320. break;
  8321. }
  8322. case ".":
  8323. case "e":
  8324. {
  8325. cache.push(d[i]);
  8326. break;
  8327. }
  8328. case "-":
  8329. {
  8330. if (d[i - 1] !== "e") {
  8331. if (cache.length) {
  8332. pattern.push(cache.join(""), ",");
  8333. }
  8334. cache = [];
  8335. }
  8336. cache.push("-");
  8337. break;
  8338. }
  8339. case " ":
  8340. case ",":
  8341. {
  8342. if (cache.length) {
  8343. pattern.push(cache.join(""), ",");
  8344. cache = [];
  8345. }
  8346. break;
  8347. }
  8348. default:
  8349. {
  8350. if (/\d/.test(d[i])) {
  8351. cache.push(d[i]);
  8352. } else {
  8353. // m a c s q h v l t z情况
  8354. if (cache.length) {
  8355. pattern.push(cache.join(""), d[i]);
  8356. cache = [];
  8357. } else {
  8358. // 脑图的path格式真奇怪...偶尔就给我蹦出来一个"..V123 c..", 那空格几个意思 - -
  8359. if (pattern[pattern.length - 1] === ",") {
  8360. pattern.pop();
  8361. }
  8362. pattern.push(d[i]);
  8363. }
  8364. }
  8365. if (i + 1 === l) {
  8366. if (cache.length) {
  8367. pattern.push(cache.join(""));
  8368. }
  8369. dealWithPattern(pattern);
  8370. strArr.push(pattern.join(""));
  8371. cache = null;
  8372. pattern = null;
  8373. }
  8374. }
  8375. }
  8376. }
  8377. return strArr.join("");
  8378. }
  8379. function replaceWithNode(svgNode, parentX, parentY) {
  8380. if (!svgNode) {
  8381. return;
  8382. }
  8383. if (svgNode.tagName === "defs") {
  8384. return;
  8385. }
  8386. if (svgNode.getAttribute("fill") === "transparent") {
  8387. svgNode.setAttribute("fill", "none");
  8388. }
  8389. if (svgNode.getAttribute("marker-end")) {
  8390. svgNode.removeAttribute("marker-end");
  8391. }
  8392. parentX = parentX || 0;
  8393. parentY = parentY || 0;
  8394. if (svgNode.getAttribute("transform")) {
  8395. var ctm = getTransformToElement(svgNode, svgNode.parentElement);
  8396. parentX -= ctm.e;
  8397. parentY -= ctm.f;
  8398. svgNode.removeAttribute("transform");
  8399. }
  8400. switch (svgNode.tagName.toLowerCase()) {
  8401. case "g":
  8402. break;
  8403. case "path":
  8404. {
  8405. var d = svgNode.getAttribute("d");
  8406. if (d) {
  8407. d = dealWithPath(d, function(pattern) {
  8408. switch (pattern[0]) {
  8409. case "V":
  8410. {
  8411. pattern[1] = +pattern[1] - parentY;
  8412. break;
  8413. }
  8414. case "H":
  8415. {
  8416. pattern[1] = +pattern[1] - parentX;
  8417. break;
  8418. }
  8419. case "M":
  8420. case "L":
  8421. case "T":
  8422. {
  8423. pattern[1] = +pattern[1] - parentX;
  8424. pattern[3] = +pattern[3] - parentY;
  8425. break;
  8426. }
  8427. case "Q":
  8428. case "S":
  8429. {
  8430. pattern[1] = +pattern[1] - parentX;
  8431. pattern[3] = +pattern[3] - parentY;
  8432. pattern[5] = +pattern[5] - parentX;
  8433. pattern[7] = +pattern[7] - parentY;
  8434. break;
  8435. }
  8436. case "A":
  8437. {
  8438. pattern[11] = +pattern[11] - parentX;
  8439. pattern[13] = +pattern[13] - parentY;
  8440. break;
  8441. }
  8442. case "C":
  8443. {
  8444. pattern[1] = +pattern[1] - parentX;
  8445. pattern[3] = +pattern[3] - parentY;
  8446. pattern[5] = +pattern[5] - parentX;
  8447. pattern[7] = +pattern[7] - parentY;
  8448. pattern[9] = +pattern[9] - parentX;
  8449. pattern[11] = +pattern[11] - parentY;
  8450. }
  8451. }
  8452. });
  8453. svgNode.setAttribute("d", d);
  8454. svgNode.removeAttribute("transform");
  8455. }
  8456. return;
  8457. }
  8458. case "image":
  8459. case "text":
  8460. {
  8461. if (parentX && parentY) {
  8462. var x = +svgNode.getAttribute("x") || 0, y = +svgNode.getAttribute("y") || 0;
  8463. svgNode.setAttribute("x", x - parentX);
  8464. svgNode.setAttribute("y", y - parentY);
  8465. }
  8466. if (svgNode.getAttribute("dominant-baseline")) {
  8467. svgNode.removeAttribute("dominant-baseline");
  8468. svgNode.setAttribute("dy", ".8em");
  8469. }
  8470. svgNode.removeAttribute("transform");
  8471. return;
  8472. }
  8473. }
  8474. if (svgNode.children) {
  8475. for (var i = 0, l = svgNode.children.length; i < l; i++) {
  8476. replaceWithNode(svgNode.children[i], parentX, parentY);
  8477. }
  8478. }
  8479. }
  8480. svgDom.style.visibility = "hidden";
  8481. replaceWithNode(svgDom, x || 0, y || 0);
  8482. svgDom.style.visibility = "visible";
  8483. }
  8484. data.registerProtocol("svg", module.exports = {
  8485. fileDescription: "SVG 矢量图",
  8486. fileExtension: ".svg",
  8487. mineType: "image/svg+xml",
  8488. dataType: "text",
  8489. encode: function(json, minder) {
  8490. var paper = minder.getPaper(), paperTransform = paper.shapeNode.getAttribute("transform"), svgXml, svgContainer, svgDom, renderContainer = minder.getRenderContainer(), renderBox = renderContainer.getRenderBox(), transform = renderContainer.getTransform(), width = renderBox.width, height = renderBox.height, padding = 20;
  8491. paper.shapeNode.setAttribute("transform", "translate(0.5, 0.5)");
  8492. svgXml = paper.container.innerHTML;
  8493. paper.shapeNode.setAttribute("transform", paperTransform);
  8494. svgContainer = document.createElement("div");
  8495. document.body.appendChild(svgContainer);
  8496. svgContainer.innerHTML = svgXml;
  8497. svgDom = svgContainer.querySelector("svg");
  8498. svgDom.setAttribute("width", width + padding * 2 | 0);
  8499. svgDom.setAttribute("height", height + padding * 2 | 0);
  8500. svgDom.setAttribute("style", "background: " + minder.getStyle("background"));
  8501. //"font-family: Arial, Microsoft Yahei, Heiti SC; " +
  8502. svgDom.setAttribute("viewBox", [ 0, 0, width + padding * 2 | 0, height + padding * 2 | 0 ].join(" "));
  8503. tempSvgContainer = document.createElement("div");
  8504. cleanSVG(svgDom, renderBox.x - padding | 0, renderBox.y - padding | 0);
  8505. document.body.removeChild(svgContainer);
  8506. tempSvgContainer.appendChild(svgDom);
  8507. // need a xml with width and height
  8508. svgXml = tempSvgContainer.innerHTML;
  8509. // svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined
  8510. svgXml = svgXml.replace(/&nbsp;/g, "&#xa0;");
  8511. // svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined
  8512. return svgXml;
  8513. }
  8514. });
  8515. }
  8516. };
  8517. //src/protocol/text.js
  8518. _p[68] = {
  8519. value: function(require, exports, module) {
  8520. var data = _p.r(12);
  8521. var Browser = _p.r(17).Browser;
  8522. /**
  8523. * @Desc: 增加对不容浏览器下节点中文本\t匹配的处理,不同浏览器下\t无法正确匹配,导致无法使用TAB来批量导入节点
  8524. * @Editor: Naixor
  8525. * @Date: 2015.9.17
  8526. */
  8527. var LINE_ENDING = "\r", LINE_ENDING_SPLITER = /\r\n|\r|\n/, TAB_CHAR = function(Browser) {
  8528. if (Browser.gecko) {
  8529. return {
  8530. REGEXP: new RegExp("^(\t|" + String.fromCharCode(160, 160, 32, 160) + ")"),
  8531. DELETE: new RegExp("^(\t|" + String.fromCharCode(160, 160, 32, 160) + ")+")
  8532. };
  8533. } else if (Browser.ie || Browser.edge) {
  8534. // ie系列和edge比较特别,\t在div中会被直接转义成SPACE故只好使用SPACE来做处理
  8535. return {
  8536. REGEXP: new RegExp("^(" + String.fromCharCode(32) + "|" + String.fromCharCode(160) + ")"),
  8537. DELETE: new RegExp("^(" + String.fromCharCode(32) + "|" + String.fromCharCode(160) + ")+")
  8538. };
  8539. } else {
  8540. return {
  8541. REGEXP: /^(\t|\x20{4})/,
  8542. DELETE: /^(\t|\x20{4})+/
  8543. };
  8544. }
  8545. }(Browser);
  8546. function repeat(s, n) {
  8547. var result = "";
  8548. while (n--) result += s;
  8549. return result;
  8550. }
  8551. /**
  8552. * 对节点text中的换行符进行处理
  8553. * @method encodeWrap
  8554. * @param {String} nodeText MinderNode.data.text
  8555. * @return {String} \n -> '\n'; \\n -> '\\n'
  8556. */
  8557. function encodeWrap(nodeText) {
  8558. if (!nodeText) {
  8559. return "";
  8560. }
  8561. var textArr = [], WRAP_TEXT = [ "\\", "n" ];
  8562. for (var i = 0, j = 0, l = nodeText.length; i < l; i++) {
  8563. if (nodeText[i] === "\n" || nodeText[i] === "\r") {
  8564. textArr.push("\\n");
  8565. j = 0;
  8566. continue;
  8567. }
  8568. if (nodeText[i] === WRAP_TEXT[j]) {
  8569. j++;
  8570. if (j === 2) {
  8571. j = 0;
  8572. textArr.push("\\\\n");
  8573. }
  8574. continue;
  8575. }
  8576. switch (j) {
  8577. case 0:
  8578. {
  8579. textArr.push(nodeText[i]);
  8580. break;
  8581. }
  8582. case 1:
  8583. {
  8584. textArr.push(nodeText[i - 1], nodeText[i]);
  8585. }
  8586. }
  8587. j = 0;
  8588. }
  8589. return textArr.join("");
  8590. }
  8591. /**
  8592. * 将文本内容中的'\n'和'\\n'分别转换成\n和\\n
  8593. * @method decodeWrap
  8594. * @param {[type]} text [description]
  8595. * @return {[type]} [description]
  8596. */
  8597. function decodeWrap(text) {
  8598. if (!text) {
  8599. return "";
  8600. }
  8601. var textArr = [], WRAP_TEXT = [ "\\", "\\", "n" ];
  8602. for (var i = 0, j = 0, l = text.length; i < l; i++) {
  8603. if (text[i] === WRAP_TEXT[j]) {
  8604. j++;
  8605. if (j === 3) {
  8606. j = 0;
  8607. textArr.push("\\n");
  8608. }
  8609. continue;
  8610. }
  8611. switch (j) {
  8612. case 0:
  8613. {
  8614. textArr.push(text[i]);
  8615. j = 0;
  8616. break;
  8617. }
  8618. case 1:
  8619. {
  8620. if (text[i] === "n") {
  8621. textArr.push("\n");
  8622. } else {
  8623. textArr.push(text[i - 1], text[i]);
  8624. }
  8625. j = 0;
  8626. break;
  8627. }
  8628. case 2:
  8629. {
  8630. textArr.push(text[i - 2]);
  8631. if (text[i] !== "\\") {
  8632. j = 0;
  8633. textArr.push(text[i - 1], text[i]);
  8634. }
  8635. break;
  8636. }
  8637. }
  8638. }
  8639. return textArr.join("");
  8640. }
  8641. function encode(json, level) {
  8642. var local = "";
  8643. level = level || 0;
  8644. local += repeat("\t", level);
  8645. local += encodeWrap(json.data.text) + LINE_ENDING;
  8646. if (json.children) {
  8647. json.children.forEach(function(child) {
  8648. local += encode(child, level + 1);
  8649. });
  8650. }
  8651. return local;
  8652. }
  8653. function isEmpty(line) {
  8654. return !/\S/.test(line);
  8655. }
  8656. function getLevel(line) {
  8657. var level = 0;
  8658. while (TAB_CHAR.REGEXP.test(line)) {
  8659. line = line.replace(TAB_CHAR.REGEXP, "");
  8660. level++;
  8661. }
  8662. return level;
  8663. }
  8664. function getNode(line) {
  8665. return {
  8666. data: {
  8667. text: decodeWrap(line.replace(TAB_CHAR.DELETE, ""))
  8668. }
  8669. };
  8670. }
  8671. function decode(local) {
  8672. var json, parentMap = {}, lines = local.split(LINE_ENDING_SPLITER), line, level, node;
  8673. function addChild(parent, child) {
  8674. var children = parent.children || (parent.children = []);
  8675. children.push(child);
  8676. }
  8677. for (var i = 0; i < lines.length; i++) {
  8678. line = lines[i];
  8679. if (isEmpty(line)) continue;
  8680. level = getLevel(line);
  8681. node = getNode(line);
  8682. if (level === 0) {
  8683. if (json) {
  8684. throw new Error("Invalid local format");
  8685. }
  8686. json = node;
  8687. } else {
  8688. if (!parentMap[level - 1]) {
  8689. throw new Error("Invalid local format");
  8690. }
  8691. addChild(parentMap[level - 1], node);
  8692. }
  8693. parentMap[level] = node;
  8694. }
  8695. return json;
  8696. }
  8697. /**
  8698. * @Desc: 增加一个将当前选中节点转换成text的方法
  8699. * @Editor: Naixor
  8700. * @Date: 2015.9.21
  8701. */
  8702. function Node2Text(node) {
  8703. function exportNode(node) {
  8704. var exported = {};
  8705. exported.data = node.getData();
  8706. var childNodes = node.getChildren();
  8707. exported.children = [];
  8708. for (var i = 0; i < childNodes.length; i++) {
  8709. exported.children.push(exportNode(childNodes[i]));
  8710. }
  8711. return exported;
  8712. }
  8713. if (!node) return;
  8714. if (/^\s*$/.test(node.data.text)) {
  8715. node.data.text = "分支主题";
  8716. }
  8717. return encode(exportNode(node));
  8718. }
  8719. data.registerProtocol("text", module.exports = {
  8720. fileDescription: "大纲文本",
  8721. fileExtension: ".txt",
  8722. dataType: "text",
  8723. mineType: "text/plain",
  8724. encode: function(json) {
  8725. return encode(json.root, 0);
  8726. },
  8727. decode: function(local) {
  8728. return decode(local);
  8729. },
  8730. Node2Text: function(node) {
  8731. return Node2Text(node);
  8732. }
  8733. });
  8734. }
  8735. };
  8736. //src/template/default.js
  8737. /**
  8738. * @fileOverview
  8739. *
  8740. * 默认模板 - 脑图模板
  8741. *
  8742. * @author: techird
  8743. * @copyright: Baidu FEX, 2014
  8744. */
  8745. _p[69] = {
  8746. value: function(require, exports, module) {
  8747. var template = _p.r(31);
  8748. template.register("default", {
  8749. getLayout: function(node) {
  8750. if (node.getData("layout")) return node.getData("layout");
  8751. var level = node.getLevel();
  8752. // 根节点
  8753. if (level === 0) {
  8754. return "mind";
  8755. }
  8756. // 一级节点
  8757. if (level === 1) {
  8758. return node.getLayoutPointPreview().x > 0 ? "right" : "left";
  8759. }
  8760. return node.parent.getLayout();
  8761. },
  8762. getConnect: function(node) {
  8763. if (node.getLevel() == 1) return "arc";
  8764. return "under";
  8765. }
  8766. });
  8767. }
  8768. };
  8769. //src/template/filetree.js
  8770. /**
  8771. * @fileOverview
  8772. *
  8773. * 文件夹模板
  8774. *
  8775. * @author: techird
  8776. * @copyright: Baidu FEX, 2014
  8777. */
  8778. _p[70] = {
  8779. value: function(require, exports, module) {
  8780. var template = _p.r(31);
  8781. template.register("filetree", {
  8782. getLayout: function(node) {
  8783. if (node.getData("layout")) return node.getData("layout");
  8784. if (node.isRoot()) return "bottom";
  8785. return "filetree-down";
  8786. },
  8787. getConnect: function(node) {
  8788. if (node.getLevel() == 1) {
  8789. return "poly";
  8790. }
  8791. return "l";
  8792. }
  8793. });
  8794. }
  8795. };
  8796. //src/template/fish-bone.js
  8797. /**
  8798. * @fileOverview
  8799. *
  8800. * 默认模板 - 鱼骨头模板
  8801. *
  8802. * @author: techird
  8803. * @copyright: Baidu FEX, 2014
  8804. */
  8805. _p[71] = {
  8806. value: function(require, exports, module) {
  8807. var template = _p.r(31);
  8808. template.register("fish-bone", {
  8809. getLayout: function(node) {
  8810. if (node.getData("layout")) return node.getData("layout");
  8811. var level = node.getLevel();
  8812. // 根节点
  8813. if (level === 0) {
  8814. return "fish-bone-master";
  8815. }
  8816. // 一级节点
  8817. if (level === 1) {
  8818. return "fish-bone-slave";
  8819. }
  8820. return node.getLayoutPointPreview().y > 0 ? "filetree-up" : "filetree-down";
  8821. },
  8822. getConnect: function(node) {
  8823. switch (node.getLevel()) {
  8824. case 1:
  8825. return "fish-bone-master";
  8826. case 2:
  8827. return "line";
  8828. default:
  8829. return "l";
  8830. }
  8831. }
  8832. });
  8833. }
  8834. };
  8835. //src/template/right.js
  8836. /**
  8837. * @fileOverview
  8838. *
  8839. * 往右布局结构模板
  8840. *
  8841. * @author: techird
  8842. * @copyright: Baidu FEX, 2014
  8843. */
  8844. _p[72] = {
  8845. value: function(require, exports, module) {
  8846. var template = _p.r(31);
  8847. template.register("right", {
  8848. getLayout: function(node) {
  8849. return node.getData("layout") || "right";
  8850. },
  8851. getConnect: function(node) {
  8852. if (node.getLevel() == 1) return "arc";
  8853. return "bezier";
  8854. }
  8855. });
  8856. }
  8857. };
  8858. //src/template/structure.js
  8859. /**
  8860. * @fileOverview
  8861. *
  8862. * 组织结构图模板
  8863. *
  8864. * @author: techird
  8865. * @copyright: Baidu FEX, 2014
  8866. */
  8867. _p[73] = {
  8868. value: function(require, exports, module) {
  8869. var template = _p.r(31);
  8870. template.register("structure", {
  8871. getLayout: function(node) {
  8872. return node.getData("layout") || "bottom";
  8873. },
  8874. getConnect: function(node) {
  8875. return "poly";
  8876. }
  8877. });
  8878. }
  8879. };
  8880. //src/template/tianpan.js
  8881. /**
  8882. * @fileOverview
  8883. *
  8884. * 天盘模板
  8885. *
  8886. * @author: along
  8887. * @copyright: bpd729@163.com, 2015
  8888. */
  8889. _p[74] = {
  8890. value: function(require, exports, module) {
  8891. var template = _p.r(31);
  8892. template.register("tianpan", {
  8893. getLayout: function(node) {
  8894. if (node.getData("layout")) return node.getData("layout");
  8895. var level = node.getLevel();
  8896. // 根节点
  8897. if (level === 0) {
  8898. return "tianpan";
  8899. }
  8900. return node.parent.getLayout();
  8901. },
  8902. getConnect: function(node) {
  8903. return "arc_tp";
  8904. }
  8905. });
  8906. }
  8907. };
  8908. //src/theme/default.js
  8909. _p[75] = {
  8910. value: function(require, exports, module) {
  8911. var theme = _p.r(32);
  8912. [ "classic", "classic-compact" ].forEach(function(name) {
  8913. var compact = name == "classic-compact";
  8914. /* jscs:disable maximumLineLength */
  8915. theme.register(name, {
  8916. background: '#3A4144 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=") repeat',
  8917. "root-color": "#430",
  8918. "root-background": "#e9df98",
  8919. "root-stroke": "#e9df98",
  8920. "root-font-size": 24,
  8921. "root-padding": compact ? [ 10, 25 ] : [ 15, 25 ],
  8922. "root-margin": compact ? [ 15, 25 ] : [ 30, 100 ],
  8923. "root-radius": 30,
  8924. "root-space": 10,
  8925. "root-shadow": "rgba(0, 0, 0, .25)",
  8926. "main-color": "#333",
  8927. "main-background": "#a4c5c0",
  8928. "main-stroke": "#a4c5c0",
  8929. "main-font-size": 16,
  8930. "main-padding": compact ? [ 5, 15 ] : [ 6, 20 ],
  8931. "main-margin": compact ? [ 5, 10 ] : 20,
  8932. "main-radius": 10,
  8933. "main-space": 5,
  8934. "main-shadow": "rgba(0, 0, 0, .25)",
  8935. "sub-color": "white",
  8936. "sub-background": "transparent",
  8937. "sub-stroke": "none",
  8938. "sub-font-size": 12,
  8939. "sub-padding": [ 5, 10 ],
  8940. "sub-margin": compact ? [ 5, 10 ] : [ 15, 20 ],
  8941. "sub-tree-margin": 30,
  8942. "sub-radius": 5,
  8943. "sub-space": 5,
  8944. "connect-color": "white",
  8945. "connect-width": 2,
  8946. "main-connect-width": 3,
  8947. "connect-radius": 5,
  8948. "selected-background": "rgb(254, 219, 0)",
  8949. "selected-stroke": "rgb(254, 219, 0)",
  8950. "selected-color": "black",
  8951. "marquee-background": "rgba(255,255,255,.3)",
  8952. "marquee-stroke": "white",
  8953. "drop-hint-color": "yellow",
  8954. "sub-drop-hint-width": 2,
  8955. "main-drop-hint-width": 4,
  8956. "root-drop-hint-width": 4,
  8957. "order-hint-area-color": "rgba(0, 255, 0, .5)",
  8958. "order-hint-path-color": "#0f0",
  8959. "order-hint-path-width": 1,
  8960. "text-selection-color": "rgb(27,171,255)",
  8961. "line-height": 1.5
  8962. });
  8963. });
  8964. }
  8965. };
  8966. //src/theme/fish.js
  8967. _p[76] = {
  8968. value: function(require, exports, module) {
  8969. var theme = _p.r(32);
  8970. theme.register("fish", {
  8971. background: '#3A4144 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=") repeat',
  8972. "root-color": "#430",
  8973. "root-background": "#e9df98",
  8974. "root-stroke": "#e9df98",
  8975. "root-font-size": 24,
  8976. "root-padding": [ 35, 35 ],
  8977. "root-margin": 30,
  8978. "root-radius": 100,
  8979. "root-space": 10,
  8980. "root-shadow": "rgba(0, 0, 0, .25)",
  8981. "main-color": "#333",
  8982. "main-background": "#a4c5c0",
  8983. "main-stroke": "#a4c5c0",
  8984. "main-font-size": 16,
  8985. "main-padding": [ 6, 20 ],
  8986. "main-margin": [ 20, 20 ],
  8987. "main-radius": 5,
  8988. "main-space": 5,
  8989. "main-shadow": "rgba(0, 0, 0, .25)",
  8990. "sub-color": "black",
  8991. "sub-background": "white",
  8992. "sub-stroke": "white",
  8993. "sub-font-size": 12,
  8994. "sub-padding": [ 5, 10 ],
  8995. "sub-margin": [ 10 ],
  8996. "sub-radius": 5,
  8997. "sub-space": 5,
  8998. "connect-color": "white",
  8999. "connect-width": 3,
  9000. "main-connect-width": 3,
  9001. "connect-radius": 5,
  9002. "selected-background": "rgb(254, 219, 0)",
  9003. "selected-stroke": "rgb(254, 219, 0)",
  9004. "marquee-background": "rgba(255,255,255,.3)",
  9005. "marquee-stroke": "white",
  9006. "drop-hint-color": "yellow",
  9007. "drop-hint-width": 4,
  9008. "order-hint-area-color": "rgba(0, 255, 0, .5)",
  9009. "order-hint-path-color": "#0f0",
  9010. "order-hint-path-width": 1,
  9011. "text-selection-color": "rgb(27,171,255)",
  9012. "line-height": 1.5
  9013. });
  9014. }
  9015. };
  9016. //src/theme/fresh.js
  9017. _p[77] = {
  9018. value: function(require, exports, module) {
  9019. var kity = _p.r(17);
  9020. var theme = _p.r(32);
  9021. function hsl(h, s, l) {
  9022. return kity.Color.createHSL(h, s, l);
  9023. }
  9024. function generate(h, compat) {
  9025. return {
  9026. background: "#fbfbfb",
  9027. "root-color": "white",
  9028. "root-background": hsl(h, 37, 60),
  9029. "root-stroke": hsl(h, 37, 60),
  9030. "root-font-size": 16,
  9031. "root-padding": compat ? [ 6, 12 ] : [ 12, 24 ],
  9032. "root-margin": compat ? 10 : [ 30, 100 ],
  9033. "root-radius": 5,
  9034. "root-space": 10,
  9035. "main-color": "black",
  9036. "main-background": hsl(h, 33, 95),
  9037. "main-stroke": hsl(h, 37, 60),
  9038. "main-stroke-width": 1,
  9039. "main-font-size": 14,
  9040. "main-padding": [ 6, 20 ],
  9041. "main-margin": compat ? 8 : 20,
  9042. "main-radius": 3,
  9043. "main-space": 5,
  9044. "sub-color": "black",
  9045. "sub-background": "transparent",
  9046. "sub-stroke": "none",
  9047. "sub-font-size": 12,
  9048. "sub-padding": compat ? [ 3, 5 ] : [ 5, 10 ],
  9049. "sub-margin": compat ? [ 4, 8 ] : [ 15, 20 ],
  9050. "sub-radius": 5,
  9051. "sub-space": 5,
  9052. "connect-color": hsl(h, 37, 60),
  9053. "connect-width": 1,
  9054. "connect-radius": 5,
  9055. "selected-stroke": hsl(h, 26, 30),
  9056. "selected-stroke-width": "3",
  9057. "blur-selected-stroke": hsl(h, 10, 60),
  9058. "marquee-background": hsl(h, 100, 80).set("a", .1),
  9059. "marquee-stroke": hsl(h, 37, 60),
  9060. "drop-hint-color": hsl(h, 26, 35),
  9061. "drop-hint-width": 5,
  9062. "order-hint-area-color": hsl(h, 100, 30).set("a", .5),
  9063. "order-hint-path-color": hsl(h, 100, 25),
  9064. "order-hint-path-width": 1,
  9065. "text-selection-color": hsl(h, 100, 20),
  9066. "line-height": 1.5
  9067. };
  9068. }
  9069. var plans = {
  9070. red: 0,
  9071. soil: 25,
  9072. green: 122,
  9073. blue: 204,
  9074. purple: 246,
  9075. pink: 334
  9076. };
  9077. var name;
  9078. for (name in plans) {
  9079. theme.register("fresh-" + name, generate(plans[name]));
  9080. theme.register("fresh-" + name + "-compat", generate(plans[name], true));
  9081. }
  9082. }
  9083. };
  9084. //src/theme/snow.js
  9085. _p[78] = {
  9086. value: function(require, exports, module) {
  9087. var theme = _p.r(32);
  9088. [ "snow", "snow-compact" ].forEach(function(name) {
  9089. var compact = name == "snow-compact";
  9090. /* jscs:disable maximumLineLength */
  9091. theme.register(name, {
  9092. background: '#3A4144 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=") repeat',
  9093. "root-color": "#430",
  9094. "root-background": "#e9df98",
  9095. "root-stroke": "#e9df98",
  9096. "root-font-size": 24,
  9097. "root-padding": compact ? [ 5, 10 ] : [ 15, 25 ],
  9098. "root-margin": compact ? 15 : 30,
  9099. "root-radius": 5,
  9100. "root-space": 10,
  9101. "root-shadow": "rgba(0, 0, 0, .25)",
  9102. "main-color": "#333",
  9103. "main-background": "#a4c5c0",
  9104. "main-stroke": "#a4c5c0",
  9105. "main-font-size": 16,
  9106. "main-padding": compact ? [ 4, 10 ] : [ 6, 20 ],
  9107. "main-margin": compact ? [ 5, 10 ] : [ 20, 40 ],
  9108. "main-radius": 5,
  9109. "main-space": 5,
  9110. "main-shadow": "rgba(0, 0, 0, .25)",
  9111. "sub-color": "black",
  9112. "sub-background": "white",
  9113. "sub-stroke": "white",
  9114. "sub-font-size": 12,
  9115. "sub-padding": [ 5, 10 ],
  9116. "sub-margin": compact ? [ 5, 10 ] : [ 10, 20 ],
  9117. "sub-radius": 5,
  9118. "sub-space": 5,
  9119. "connect-color": "white",
  9120. "connect-width": 2,
  9121. "main-connect-width": 3,
  9122. "connect-radius": 5,
  9123. "selected-background": "rgb(254, 219, 0)",
  9124. "selected-stroke": "rgb(254, 219, 0)",
  9125. "marquee-background": "rgba(255,255,255,.3)",
  9126. "marquee-stroke": "white",
  9127. "drop-hint-color": "yellow",
  9128. "drop-hint-width": 4,
  9129. "order-hint-area-color": "rgba(0, 255, 0, .5)",
  9130. "order-hint-path-color": "#0f0",
  9131. "order-hint-path-width": 1,
  9132. "text-selection-color": "rgb(27,171,255)",
  9133. "line-height": 1.5
  9134. });
  9135. });
  9136. }
  9137. };
  9138. //src/theme/tianpan.js
  9139. _p[79] = {
  9140. value: function(require, exports, module) {
  9141. var theme = _p.r(32);
  9142. [ "tianpan", "tianpan-compact" ].forEach(function(name) {
  9143. var compact = name == "tianpan-compact";
  9144. theme.register(name, {
  9145. background: '#3A4144 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=") repeat',
  9146. "root-color": "#430",
  9147. "root-background": "#e9df98",
  9148. "root-stroke": "#e9df98",
  9149. "root-font-size": 25,
  9150. "root-padding": compact ? 15 : 20,
  9151. "root-margin": compact ? [ 15, 25 ] : 100,
  9152. "root-radius": 30,
  9153. "root-space": 10,
  9154. "root-shadow": "rgba(0, 0, 0, .25)",
  9155. "root-shape": "circle",
  9156. "main-color": "#333",
  9157. "main-background": "#a4c5c0",
  9158. "main-stroke": "#a4c5c0",
  9159. "main-font-size": 15,
  9160. "main-padding": compact ? 10 : 12,
  9161. "main-margin": compact ? 10 : 12,
  9162. "main-radius": 10,
  9163. "main-space": 5,
  9164. "main-shadow": "rgba(0, 0, 0, .25)",
  9165. "main-shape": "circle",
  9166. "sub-color": "#333",
  9167. "sub-background": "#99ca6a",
  9168. "sub-stroke": "#a4c5c0",
  9169. "sub-font-size": 13,
  9170. "sub-padding": 5,
  9171. "sub-margin": compact ? 6 : 10,
  9172. "sub-tree-margin": 30,
  9173. "sub-radius": 5,
  9174. "sub-space": 5,
  9175. "sub-shadow": "rgba(0, 0, 0, .25)",
  9176. "sub-shape": "circle",
  9177. "connect-color": "white",
  9178. "connect-width": 2,
  9179. "main-connect-width": 3,
  9180. "connect-radius": 5,
  9181. "selected-background": "rgb(254, 219, 0)",
  9182. "selected-stroke": "rgb(254, 219, 0)",
  9183. "selected-color": "black",
  9184. "marquee-background": "rgba(255,255,255,.3)",
  9185. "marquee-stroke": "white",
  9186. "drop-hint-color": "yellow",
  9187. "sub-drop-hint-width": 2,
  9188. "main-drop-hint-width": 4,
  9189. "root-drop-hint-width": 4,
  9190. "order-hint-area-color": "rgba(0, 255, 0, .5)",
  9191. "order-hint-path-color": "#0f0",
  9192. "order-hint-path-width": 1,
  9193. "text-selection-color": "rgb(27,171,255)",
  9194. "line-height": 1.4
  9195. });
  9196. });
  9197. }
  9198. };
  9199. //src/theme/wire.js
  9200. _p[80] = {
  9201. value: function(require, exports, module) {
  9202. var theme = _p.r(32);
  9203. theme.register("wire", {
  9204. background: "black",
  9205. color: "#999",
  9206. stroke: "none",
  9207. padding: 10,
  9208. margin: 20,
  9209. "font-size": 14,
  9210. "connect-color": "#999",
  9211. "connect-width": 1,
  9212. "selected-background": "#999",
  9213. "selected-color": "black",
  9214. "marquee-background": "rgba(255,255,255,.3)",
  9215. "marquee-stroke": "white",
  9216. "drop-hint-color": "yellow",
  9217. "sub-drop-hint-width": 2,
  9218. "main-drop-hint-width": 4,
  9219. "root-drop-hint-width": 4,
  9220. "order-hint-area-color": "rgba(0, 255, 0, .5)",
  9221. "order-hint-path-color": "#0f0",
  9222. "order-hint-path-width": 1,
  9223. "text-selection-color": "rgb(27,171,255)",
  9224. "line-height": 1.5
  9225. });
  9226. }
  9227. };
  9228. var moduleMapping = {
  9229. "expose-kityminder": 34
  9230. };
  9231. function use(name) {
  9232. _p.r([ moduleMapping[name] ]);
  9233. }
  9234. use('expose-kityminder');
  9235. })();