├── .gitignore ├── README.md ├── assets ├── draghandler.jpg ├── gear.png ├── icon-128.png ├── icon-192.png ├── icon-766.png ├── icon.drawio ├── iconslack.png ├── nightsky.jpg ├── operators │ ├── descbox.png │ ├── inspector.png │ ├── itemcluster.png │ ├── list.png │ ├── scriptrunner.png │ └── wkflow.PNG ├── purplestars.jpeg └── structurediagram.png ├── build ├── cat.js ├── polymorph_static.js ├── unit_core.html └── unit_core.js ├── devel ├── helpful debug scripts │ └── rect_ctr_to_itemcluster_tree.js └── pre-commit ├── docs ├── README.md ├── dev │ ├── README.md │ ├── authentication.md │ ├── conventions.md │ ├── core.md │ ├── core_tests.md │ └── items │ │ ├── dates.md │ │ ├── linking.md │ │ ├── linking_v2.md │ │ ├── overview.md │ │ └── synchronisation.md ├── index.html ├── operators │ ├── container.md │ ├── gitlite.md │ ├── scriptrunner_reference.md │ ├── synergist.2.md │ ├── terminal.md │ ├── textflow.md │ ├── time_syntax.md │ └── workflowish.md ├── operators_general │ ├── overview.md │ ├── subframing.md │ └── upgrade_checklist.md ├── savesources │ ├── firebase.md │ ├── hilagit.md │ ├── monogit.md │ ├── savesources.md │ ├── saving.md │ └── shenanigans │ │ ├── delta │ │ ├── links │ │ ├── options.md │ │ └── vertical pin script ├── user │ ├── datamodel.md │ ├── keyfeats.md │ ├── load event timing.md │ ├── local_machine_data.md │ ├── overview.md │ ├── rects.md │ ├── small todos.md │ ├── uimodel.md │ └── viewdata.md ├── versions │ └── unit_core.md └── workflows │ ├── common_scripting_tasks.md │ └── import_obj_arr_into_itemcluster.md ├── filemanager.js ├── index.html ├── manifest.json ├── pwa.js └── src ├── 3pt ├── Treant.css ├── Treant.js ├── chart.js ├── firebase-app.js ├── firebase-database.js ├── firebase-firestore.js ├── fullcalendar.min.css ├── fullcalendar.min.js ├── fullcalendar │ ├── core │ │ ├── locales-all.js │ │ ├── locales-all.min.js │ │ ├── locales │ │ │ ├── af.js │ │ │ ├── ar-dz.js │ │ │ ├── ar-kw.js │ │ │ ├── ar-ly.js │ │ │ ├── ar-ma.js │ │ │ ├── ar-sa.js │ │ │ ├── ar-tn.js │ │ │ ├── ar.js │ │ │ ├── bg.js │ │ │ ├── bs.js │ │ │ ├── ca.js │ │ │ ├── cs.js │ │ │ ├── da.js │ │ │ ├── de.js │ │ │ ├── el.js │ │ │ ├── en-au.js │ │ │ ├── en-gb.js │ │ │ ├── en-nz.js │ │ │ ├── es-us.js │ │ │ ├── es.js │ │ │ ├── et.js │ │ │ ├── eu.js │ │ │ ├── fa.js │ │ │ ├── fi.js │ │ │ ├── fr-ca.js │ │ │ ├── fr-ch.js │ │ │ ├── fr.js │ │ │ ├── gl.js │ │ │ ├── he.js │ │ │ ├── hi.js │ │ │ ├── hr.js │ │ │ ├── hu.js │ │ │ ├── id.js │ │ │ ├── is.js │ │ │ ├── it.js │ │ │ ├── ja.js │ │ │ ├── ka.js │ │ │ ├── kk.js │ │ │ ├── ko.js │ │ │ ├── lb.js │ │ │ ├── lt.js │ │ │ ├── lv.js │ │ │ ├── mk.js │ │ │ ├── ms.js │ │ │ ├── nb.js │ │ │ ├── nl.js │ │ │ ├── nn.js │ │ │ ├── pl.js │ │ │ ├── pt-br.js │ │ │ ├── pt.js │ │ │ ├── ro.js │ │ │ ├── ru.js │ │ │ ├── sk.js │ │ │ ├── sl.js │ │ │ ├── sq.js │ │ │ ├── sr-cyrl.js │ │ │ ├── sr.js │ │ │ ├── sv.js │ │ │ ├── th.js │ │ │ ├── tr.js │ │ │ ├── uk.js │ │ │ ├── vi.js │ │ │ ├── zh-cn.js │ │ │ └── zh-tw.js │ │ ├── main.css │ │ ├── main.js │ │ ├── main.min.css │ │ └── main.min.js │ ├── daygrid │ │ ├── main.css │ │ ├── main.js │ │ ├── main.min.css │ │ └── main.min.js │ ├── interaction │ │ ├── main.js │ │ └── main.min.js │ ├── list │ │ ├── main.css │ │ ├── main.js │ │ ├── main.min.css │ │ └── main.min.js │ └── timegrid │ │ ├── main.css │ │ ├── main.js │ │ ├── main.min.css │ │ └── main.min.js ├── jquery.min.js ├── jscolor.js ├── localforage.min.js ├── moment.min.js ├── quill.bubble.css ├── quill.min.js ├── quill.snow.css ├── showdown.js ├── svg.foreignobject.js ├── svg.min.js └── x-frame-bypass.js ├── core.js ├── core_modules ├── core │ ├── core.clip.js │ ├── core.container.js │ ├── core.dataUtils.js │ ├── core.debug.js │ ├── core.dedup.js │ ├── core.docLoading.js │ ├── core.itemfx.js │ ├── core.operator.js │ ├── core.phone.rect.js │ ├── core.rect.js │ ├── core.static.js │ └── core.workersync.js ├── ui │ ├── ccleaner.js │ ├── core.contextMenu.js │ ├── core.customCSS.js │ ├── core.dialog.js │ ├── core.dragdrop.js │ ├── core.loadSaveUI.js │ ├── core.main.js │ ├── core.phone.main.js │ ├── core.tutorial.js │ ├── core.view.js │ └── richText.js └── unmaintained │ ├── core.palette.js │ ├── core.serviceWorker.js │ ├── core.sharing.js │ └── core.templates.js ├── genui ├── dateparser.js ├── inductor.js ├── intervalParser.js ├── quickNotify.js └── test │ └── test.html ├── operators ├── calendar.js ├── deltaLogger.js ├── descbox.js ├── inspectolist.js ├── inspector.js ├── itemList.js ├── itemList.phone.js ├── itemList.searchsort.js ├── itemcluster │ ├── contextmenu │ │ ├── condensed_hierarchy.js │ │ ├── condensed_radial_hierarchy.js │ │ ├── entropic_hierarchy.js │ │ ├── entropy.js │ │ └── orbit.js │ ├── itemcluster.contextmenu.js │ ├── itemcluster.js │ ├── itemcluster.rapidentry.js │ ├── itemcluster.scalegrid.js │ └── itemcluster.svg.js ├── json_inspector.js ├── opSelect.js ├── phone │ └── subframe.js ├── richbox.js ├── ruigen │ ├── annipairs.js │ ├── bitstream.js │ ├── hackertext.js │ ├── kaleidocore.js │ ├── lockcore.js │ ├── matrixtext.js │ ├── orbit3d.js │ ├── radar.js │ ├── rui_operator.js │ ├── starscape.js │ └── triflow.js ├── scriptrunner.js ├── subframe.js ├── tally.js ├── template.js ├── terminal.js ├── textflow.js ├── textflow │ └── socParser.js ├── timer.js ├── unmaintained │ ├── calendar.2.js │ ├── canvas.js │ ├── chat.js │ ├── collapsigant.js │ ├── drawio.js │ ├── httree.js │ ├── iframe.js │ ├── messageStream.js │ ├── quillbox.js │ ├── reference.js │ ├── roundshow.js │ ├── ruigen.js │ ├── sorter.js │ ├── stack.js │ ├── switchboard.js │ ├── terminal2.js │ ├── tester.js │ ├── timeline.js │ ├── timer.js │ └── treant.js ├── welcome.js └── workflow │ ├── advancedentry.js │ ├── focusMode.js │ ├── search.js │ ├── workflow tests.md │ ├── workflow.phonebar.sticky.js │ ├── workflow_gitfriendly.js │ ├── workflow_gitfriendly_contextMenu.js │ ├── workflow_recursive_paste.js │ └── workflow_shim.js ├── saveSources ├── broadcastsync.js ├── deadish │ ├── firebase.js │ ├── gdrive.js │ ├── gitlite.js │ ├── websocket.js │ └── wsgit.js ├── hilagit.js ├── lobby.js ├── localforage2.js ├── merglite.js ├── monogit.js ├── outputToText.js ├── permalink.js ├── server.js └── template.js ├── unit_core.js └── utils.js /.gitignore: -------------------------------------------------------------------------------- 1 | assets/custom -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Polymorph 2 | [acenturyandabit.github.io/polymorph/](https://acenturyandabit.github.io/polymorph/) 3 | 4 | ![](https://raw.githubusercontent.com/acenturyandabit/polymorph/largeAssets/assets/readme2.gif) 5 | 6 | Polymorph is a very fancy to-do-list that puts you in charge of what it does. With a bit of creativity, you can turn Polymorph into a Knowledge Base, Contact Management System, or automate your entire workflow, without getting into all the code. 7 | 8 | Polymorph runs in your browser; out of the box, polymorph has: 9 | - A Workflowy Emulator (workflowish); 10 | - A Mind map generator (itemcluster); 11 | - A To-do list (itemList); 12 | - A scripting interface (scriptRunner) 13 | and a few other odds and ends. 14 | 15 | ## The Polymorph Edge 16 | Sure, polymorph provides you with elements such as lists, drilldowns, and graphs, but its real superpower is its **incredibly space-efficient organisation framework**. In Polymoprh, you can subdivide your window into functional rectangular areas, and imbue those areas with the elements above. Maybe you want a list next to a graph, or two lists for separate things; Polymorph can do it all. 17 | 18 | Tabs are used to provide quick configuration options and provide flexibility, and a script runner element allows you to automate parts of your workflow such as time logging and organisation. 19 | 20 | This highly modular approach allows you to take charge of your task organisation in a way that no other platform will allow (apart from building up a task management app yourself from scratch, that is.) At the same time, we know you won't be rebuilding your task management system everyday, so modification elements are out-of-the-way until you summon them with a press of a button. 21 | 22 | If you'd like to run polymorph with a server backing it, check out the self-hostable `polymorph_backend` project here: [https://github.com/acenturyandabit/polymorph_backend] 23 | ## Keeping it straight 24 | Polymorph doesn't use React or Angular or Vue. This means that anyone who knows javascript can contribute; there are no dependencies to install; and code isn't obfuscated*, meaning you can edit it during runtime from the browser. 25 | 26 | Polymorph doesn't need to run on a server, just a browser; and Polymorph will be always open source. This means anyone can fork, clone and edit, and mod to their heart's content. 27 | 28 | *: Code is concatenated instead of compiled for deployment, which prevents multiple source downloads, often a bigger load-time-killer than download. 29 | 30 | ## Contributing 31 | Check out the developer readme in `/docs/dev/README.md`, then see the issues list! I fix most of my own issues because Polymorph is my day-to-day, but there's always nice-to-haves. 32 | 33 | ### Apps I admire and have copied 34 | - Workflowy: [https://workflowy.com/] - use the workflowish operator in Polymorph for this. 35 | -------------------------------------------------------------------------------- /assets/draghandler.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/draghandler.jpg -------------------------------------------------------------------------------- /assets/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/gear.png -------------------------------------------------------------------------------- /assets/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/icon-128.png -------------------------------------------------------------------------------- /assets/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/icon-192.png -------------------------------------------------------------------------------- /assets/icon-766.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/icon-766.png -------------------------------------------------------------------------------- /assets/icon.drawio: -------------------------------------------------------------------------------- 1 | 1ZnLkqIwFIafhqVVuXBdtnY73Yu5lYtZZyQKNUCsGAedp58gAQ2mS3uqjz24kfy5EL6cJH/Ao7Ny/0myTfZZpLzwCEr3Hn30CCEIIf3XKIdWwdT3W2Ut87TV0ElY5H+4KdipuzzlW6O1khKiUPnGFpeiqvhSWRqTUtR2sZUoUkvYsDW3utEIiyUr+EWxH3mqslaNSXTSn3m+zro74zBpc0rWFTYNbzOWivpMok8enUkhVHtV7me8aOjZXOav5PYdk7xSt1SYiJ9f63hbVurbd/YyT7+oh2QStq38ZsXOPLDprDp0BKTYVSlvGkEendZZrvhiw5ZNbq0HXWuZKgudwvpylRfFTBRCHuvSqY6Aue7QdKuk+MW7nEpUuvrU3JtLxfevPhTuUekg46LkSh50EVMhNnBNePkmWZ+GKjRSdj5KnchMdKz7hk8A9YVh+AaeESzPBxzNQXniyAaaXALFyEUUQxGNR07UpzbR0EHUGaM+FNEEluhjCEyUIpvoBN8YpAQsSLuGR8s0JDZT7FhJAwdSsIUU0+tEdTPaBvDrNNl203qDVb5vRmCIFx1/70MywAOS5LY9CY6kP1KSdBCTYfDBIAPYSQ5ulshgK+rTZ0T9xIE0AkMK7D/B102MryN1EaUUDOnYLegwSqkDqXN7j8GQAntQeMcUXkfqDFM4pMAm9O5rqe8wTD5xIO39wLszJcAmFHzmh4PTPHWcPqPgEikBOyp1zzBapDgOLaSBAykN/UumYC6qIzjamT8Zznxy6Ut7W3Cft07khsPSfx2mwfX9id7Tl5IbzkxvAiqFYioXlU5OEvQRB3wU2AuB4zTl2q7+AbFOnt5qH/POPg7Qp78= -------------------------------------------------------------------------------- /assets/iconslack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/iconslack.png -------------------------------------------------------------------------------- /assets/nightsky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/nightsky.jpg -------------------------------------------------------------------------------- /assets/operators/descbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/operators/descbox.png -------------------------------------------------------------------------------- /assets/operators/inspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/operators/inspector.png -------------------------------------------------------------------------------- /assets/operators/itemcluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/operators/itemcluster.png -------------------------------------------------------------------------------- /assets/operators/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/operators/list.png -------------------------------------------------------------------------------- /assets/operators/scriptrunner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/operators/scriptrunner.png -------------------------------------------------------------------------------- /assets/operators/wkflow.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/operators/wkflow.PNG -------------------------------------------------------------------------------- /assets/purplestars.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/purplestars.jpeg -------------------------------------------------------------------------------- /assets/structurediagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acenturyandabit/polymorph/b892ac9d7145fb999e5bc618cbba02dc05612724/assets/structurediagram.png -------------------------------------------------------------------------------- /build/unit_core.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Polymorph Unit-Core (Your Operator) / (Your Savesource) 6 | 7 | 8 | 9 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /devel/helpful debug scripts/rect_ctr_to_itemcluster_tree.js: -------------------------------------------------------------------------------- 1 | var initialGraph = Object.entries(polymorph_core.items) 2 | .filter(i => i[1]._rd || i[1]._od) 3 | .reduce((p, i) => { 4 | let t = {}; 5 | t[(i[1]._od || i[1]._rd).p] = true; 6 | p[i[0]] = { title: (i[1]._rd ? "RECT_" : "OPERT_" + i[1]._od.tabbarName + "_") + i[0], from: t, itemcluster: { viewData: {} } }; 7 | p[i[0]].itemcluster.viewData["dodb"] = { x: Math.random() * 300, y: Math.random() * 300 }; 8 | p[i[0]]["uvp2nv"] = true; 9 | return p 10 | }, {}); 11 | for (let i in initialGraph) { 12 | for (let j in initialGraph[i].from) { 13 | if (initialGraph[j]) { 14 | if (!initialGraph[j].to) { 15 | initialGraph[j].to = {} 16 | } 17 | initialGraph[j].to[i] = true; 18 | } 19 | } 20 | } 21 | console.log( 22 | JSON.stringify( 23 | initialGraph 24 | ) 25 | ) -------------------------------------------------------------------------------- /devel/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | node filemanager.js 3 | git add cat.js -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | Polymorph is an all-in-one task and knowledge management system. This page serves as the index for the user documentation for Polymorph, i.e. how you can use the various panels, save sources, and overall program, to create your task and knowledge management workflow. 3 | 4 | For developer documentation, please see [the developer docs](dev/README.md). 5 | 6 | - Operator reference 7 | - [workflowish operator](operators/workflowish.md) 8 | - Save source reference 9 | - [gitlite save source](savesources/gitlite.md) 10 | - Standalone operation 11 | - [Unit Core](versions/unit_core.md) -------------------------------------------------------------------------------- /docs/dev/authentication.md: -------------------------------------------------------------------------------- 1 | # Authentication 2 | 3 | The objectives of authentication are to ensure that people who are able to access a document can do so, and people who do not have access cannot. There should also be read vs write permissions. 4 | 5 | To do this, we need: 6 | - Identification of users/clients 7 | - Authentication of users/clients 8 | - Association between users and document-permissions. 9 | 10 | Clients and users can be managed by the server, so we will refer to clients from now on. 11 | 12 | The target user should be familiar with the regular sign up / login flows on existing websites such as Facebook. 13 | 14 | ## Design 15 | Authentication should be implemented at the `savesource` level. This is done to reduce the computational 16 | We want current and future `savesource`s to easily be able to integrate authentication. 17 | 18 | ## User stories 19 | ### As someone with an existing document, I want to store this document on a server in a way such that only the server manager and myself can access it. 20 | 1. I open my document. 21 | 2. I create a new savesource and enter the server URL and a password. 22 | 3. I press 'Save to source'. 23 | 4. The server allocates room for the document; checking for document name conflicts. 24 | 5. The server accepts the key and stores it locally in plaintext. 25 | 6. When the document is saved, the server compares the key sent and makes sure it is equal to the key saved locally. 26 | 7. When the document is retrieved, the server compares the key sent and makes sure it is equal to the key saved locally. 27 | #### Failure cases 28 | - The server is compromised 29 | - Solution: Encrypt the document so that the server cannot read it. This will not work with all save sources. 30 | - The user's connection is intercepted and the key is retrieved. 31 | - Solution: Encrypt messages using public/private key encryption. This would be a cool TODO. 32 | - Someone who knows the user's password spoofs the user. 33 | - No real solution to this. 34 | -------------------------------------------------------------------------------- /docs/dev/conventions.md: -------------------------------------------------------------------------------- 1 | # Conventions 2 | - Outerdiv > innerDiv 3 | - Internally, always pass containerIDs, rectIDs rather than live containers or rects. 4 | - As a result, containers and rects must enforce their place in polymorph_core ASAP. 5 | - Externally (for operator instantiation), we pass a container object, because that's easier to work with and reduces code duplication. 6 | - Expect `undefined` return on failure. 7 | - snake_case for variables. 8 | - camelCase for functions. -------------------------------------------------------------------------------- /docs/dev/core.md: -------------------------------------------------------------------------------- 1 | # Default parts of polymorph_core 2 | 3 | | Attribute | Defined in | Role | 4 | |-----------|------------|----- | 5 | |`polymorph_core.currentDocID` | `core.docLoading.js (polymorph_core.handleURL)`| Keeps track of the current document ID, and hence allows pointing to `polymorph_core.userData.documents[polymorph_core.currentDocID]`. 6 | -------------------------------------------------------------------------------- /docs/dev/core_tests.md: -------------------------------------------------------------------------------- 1 | - Test: Open a new window 2 | - Expected result: rect, opselect opens up. 3 | - Test: Press save>open: 4 | - If a current existing document, then open in new window 5 | - Otherwise, open in same window. -------------------------------------------------------------------------------- /docs/dev/items/dates.md: -------------------------------------------------------------------------------- 1 | # Dates 2 | Dates are stored as: 3 | ```js 4 | polymorph_core.items["abcdef123"].dateproperty={ 5 | datestring: "+1d", 6 | date:[ 7 | 8 | ] 9 | } 10 | ``` 11 | 12 | See `dateparser.js:268` for an explainer of what `` is. I'm keeping it there because docs close to code is g. -------------------------------------------------------------------------------- /docs/dev/items/linking.md: -------------------------------------------------------------------------------- 1 | # Linking 2 | 3 | To enforce links in polymorph, you may use the provided `polymorph_core.link(A,B,settings)` and corresponding `unlink` function. 4 | 5 | These automatically enforce both parent and child relations on objects, when given the link property. 6 | 7 | ## How it currently works 8 | ```javascript 9 | polymorph_core.items[id].to={ 10 | other_id:true, 11 | other_id_2:true 12 | } 13 | ``` 14 | An undirected link is indicated by a->b and b->a both being enforced. 15 | 16 | ## How it could work 17 | ### Children only, object 18 | - Quickly store data 19 | - Easily store metadata in links 20 | - Disadvantage: No ordered links. 21 | 22 | ### Parents and children, object 23 | - Easily find children and parents. 24 | - Disadvantage: Storage is doubled up 25 | 26 | ### Array of objects as children 27 | - Ordered children 28 | - Disadvantage: Searching for children is a lot slower. 29 | 30 | 31 | ### Linking TODO 32 | - Ordered children (because e.g. workflowy and you can always go back to unordered) 33 | - Enforce from-to pairs? 34 | - Get core in on the gig (anything that looks like a from-to pair will automatically be treated as a link list) 35 | 36 | 37 | -- categorical to vs dependent to are different and can/should be stored differently? 38 | -- things can belong in different categories. how to show this? 39 | --- bunches of slides containing sub-slides which are atoms of information, and can be arranged as such. 40 | --- tag slides, then have slides that contain their tagged slides. 41 | --- tables within slides? how to? if A:B and C:B, then can make a table with A vs C on B. 42 | recursive, colon separated tags. -------------------------------------------------------------------------------- /docs/dev/items/overview.md: -------------------------------------------------------------------------------- 1 | # Items 2 | Items are generic data elements in Polymorph. Since this update, items include all of: 3 | - Rects, 4 | - Operators 5 | - and your humble data element. [I will use data element to refer to anything that is not any of the above.] These are the most numerous as a user will be creating a lot of them. 6 | 7 | ## Creating Elements 8 | Elements are native javascript objects. Please don't put functions in them - they should store data only. 9 | 10 | In order to retrieve a unique id for the object, use `newID=polymorph_core.insertItem(newItem)`. 11 | 12 | Also, don't forget to fire `polymorph_core.fire('updateItem',{id:newID})` once you've created the item, so that other operators are aware of it. 13 | 14 | ## Deleting Elements 15 | 16 | 17 | 18 | 19 | ## Element properties 20 | You can use any element property you want, but you'll have to share with other operators, and the polymorph_core. Properties reserved by the polymorph_core include: 21 | - `item._rd`: Rect data. The precence of this property indicates that this item should be treated as a rect during load. 22 | - `item._od`: Operator data. The precence of this property indicates that this item should be treated as an operator during load. To read more about this, see `operators_general/common.md : ## Storage considerations`. 23 | - `item._lu_`: Last update timestamp. This is a useful thing for realtime save sources to manage versions. 24 | 25 | Some common properties include: 26 | - item.to: A map whose keys represent parent-to-child links from the current item to another item. The keys are strings which point to polymorph_core.item[]. 27 | - item.title: The title of the element. 28 | - item.itemcluster: Used by itemcluster to do its thing. 29 | -------------------------------------------------------------------------------- /docs/dev/items/synchronisation.md: -------------------------------------------------------------------------------- 1 | # Static sync vs dynamic sync 2 | I have two operators, and I want items to be shared between them. How do I do this? 3 | 4 | Active sync is if two operators "create" the same item at the same time. This means: 5 | - The operator that the user interacts with fires a `createItem` which is picked up by the second operator. 6 | - If the item is deleted in one operator, it remains visible in the other operator, unless the deleteItem is called. 7 | - We can add extra data to the item in both operators during creation. 8 | 9 | Static sync is if two operators both have the same filter properties. This means: 10 | - The operator that the user interacts with adds the fitler property. The second operator responds to the upateItem and renders the item. 11 | - If the item is deleted in one operator, it is deleted in the other. 12 | - It is quicker to setup - just set both operators' settings.filter to be the same. 13 | 14 | As may be expected, Polymorph implements both methods. I started with static sync but then realised active sync is so much more flexible. -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 26 | 31 | 32 | 33 | 34 |
35 | Back to contents 36 |
37 |
38 | 39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/operators/container.md: -------------------------------------------------------------------------------- 1 | # Containers 2 | ## Properties: 3 | - settings: (Actually a getter for polymorph_core.items[this_container_id]). 4 | - t: The type 5 | - data: The base operator's data. 6 | - outputRemaps: Event trigger output remaps. 7 | - Looks like this: {createItem:["a","b","c"]} 8 | - inputRemaps: Event trigger input remaps. 9 | - Looks like this: {from:"to"}. I might make it an array if i feel the need to but that feels really unnecessary and you can just attach more outputremaps as a workaround. I know it's not consistent to outputRemaps, but like, it's different. 10 | - tabbarName: The name of the operator on the tabspan. 11 | - p: Parent rect (or subframe). -------------------------------------------------------------------------------- /docs/operators/gitlite.md: -------------------------------------------------------------------------------- 1 | # gitlite 2 | A lightweight synchronisation method 3 | 4 | 5 | 6 | ## problems with full git 7 | - cannot (should not) change document during save process 8 | 9 | ## gitlite approach 10 | - keep local copy 11 | - for every object, know when it was last changed 12 | - gather all changes and sort. find last common change 13 | - request all changes since last common change -------------------------------------------------------------------------------- /docs/operators/scriptrunner_reference.md: -------------------------------------------------------------------------------- 1 | # Scriptrunner reference 2 | ## UI 3 | A global-to-your-code variable `uidiv` is defined, which is a HTML div. You may set the innerHTML of the `uidiv` and query from it like any other div. 4 | 5 | ## Polymorph events 6 | A global-to-your-code variable `instance` is defined. Use `instance.on(, ()=>{})` to listen to polymorph events. 7 | 8 | ## Logging 9 | A global-to-your-code variable `instance` is defined. Use `instance.log(string)` to log to an output underneath the script window. 10 | 11 | ## Persistent storage 12 | All scripts are transient in that they are run on startup and do not save data. To save persistent data, you can use the global variable `persistence`. 13 | 14 | Persistence will be stored as `polymorph_core.items[]._od.persistence`. 15 | 16 | ### Example scripts 17 | Log the name of an item whenever it changes: 18 | 19 | ```js 20 | instance.on("updateItem",(d)=>{ 21 | instance.log(polymorph_core.items[d.id]); 22 | }) 23 | ``` -------------------------------------------------------------------------------- /docs/operators/synergist.2.md: -------------------------------------------------------------------------------- 1 | # Some paradigmatic things 2 | - Views should represent the same set of data, arranged in different ways. If you want a new set of data, create a new operator. [ enforced by default option: no new view button; create creates for all views. ] 3 | - ... Except for subviews. or like, somehow figure out how to make all views with the same parent tied together. 4 | - Regular vs permanent items? Or is that too convoluted? 5 | 6 | # Settings 7 | - createAcrossViews: if true, when creating an item, create it in every view I display. 8 | - showNewViewButton: if true, then show the new view button. default false 9 | # Properties 10 | - views: IDs of all views that are displayed, in an array 11 | 12 | # Item data layout 13 | ```javascript 14 | polymorph_core.items[id].itemcluster={ 15 | viewName:"indicates if this item is a view.", 16 | viewData:{ 17 | vuid:{x:100,y:100} 18 | } 19 | } 20 | ``` 21 | 22 | itemPointerCache[id] contains me.svg.foreignObject. 23 | itemPointerCache[id].node has dataset.id = id; class is .floatingitem. 24 | movingdivs.el gives itemPointerCache[id]. 25 | 26 | 27 | 28 | ctrl click drag -> go from there 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/operators/terminal.md: -------------------------------------------------------------------------------- 1 | Interacting with the terminal over websockets: 2 | 1. create a ws server 3 | 2. on connect, send commands 4 | 5 | ws commands: 6 | - upii (\w+) (.+?) : update item $1 with $2 json. (Uses object.assign.) -------------------------------------------------------------------------------- /docs/operators/textflow.md: -------------------------------------------------------------------------------- 1 | # Issues 2 | Level of granularity: 3 | - Lines are items vs paragraphs are items 4 | - why not both? 5 | Lines are good because we keep to the granularity. 6 | Paragraphs are made up of lines. They are more rendering helpers than anything. -------------------------------------------------------------------------------- /docs/operators/time_syntax.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

Time syntax

7 |

8 | Polymorph uses a custom date parser which allows users to enter complex time expressions in a single line of text. 9 | 10 | Here are some examples: 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | lmfao 22 | to convert from a datestring to a static date in js: 23 | polymorph_core.items[id][property].datestring = new Date(polymorph_core.items[id][property].date[0].date).toLocaleString() + ">" + new Date(polymorph_core.items[id][property].date[0].endDate).toLocaleString() 24 | 25 | to force a date reparse: 26 | prop.date = dateParser.richExtractTime(prop.datestring); 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
ValueMeaning
(5/8/19|+1w 9:00am>+3h|13)Starting from 5/12/19 not inclusive, every 1 week over 13 weeks, the event runs from 9:00am to 12:00pm.(5/8/19|+1w 9:00am>7:00pm|13)Starting from 5/12/19 not inclusive, every 1 week over 13 weeks, the event runs from 9:00am to 12:00pm.
37 |

38 |

Itemcluster tips

39 |

40 | If an item is in a particular view, itemcluster will enforce a property __itemcluster_[name-of-view] = true. 41 | In this way, you can make an itemlist display the items visible in an itemcluster in a pinch. 42 | 43 | Here are some examples: 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
ValueMeaning
(5/8/19|+1w 9:00am>+3h|13)Starting form 5/12/19 not inclusive, every 1 week over 13 weeks, the event runs from 9:00am to 12:00pm.(5/8/19|+1w 9:00am>7:00pm|13)Starting form 5/12/19 not inclusive, every 1 week over 13 weeks, the event runs from 9:00am to 12:00pm.
54 |

55 | 56 | -------------------------------------------------------------------------------- /docs/operators/workflowish.md: -------------------------------------------------------------------------------- 1 | # Workflowish 2 | Workflowish copies many concepts from Workflowy. Workflowy is a recursive bullet list system which allows collapsing of the bullet lists, allowing huge amounts of information to be recursively indexed. 3 | 4 | ## Usage 5 | To load a workflowish operator, create a new tab, and then press "Workflowish" under the standard operators. 6 | ### Entering new items 7 | - On any existing line, you can press `Enter` to add a new item. 8 | - If you want to break an existing line in two, you can press `Alt/Option` + `Enter`. 9 | - If you want to create a new subitem under the current item, you can press `Shift` + `Enter`. 10 | - If you want to break an existing line in two, and then put that line under the existing one as a subitem, you can press `Alt/Option` + `Shift` + `Enter`. 11 | ### Modifying items 12 | - Click and type in any item to modify it. 13 | - To rearrange items, press `Alt` then `Up Arrow` or `Down Arrow` to move the currently selected item up or down. 14 | - To indent an item, press `Tab`. To un-indent an item, press `Shift` + `Tab`. 15 | - To show or hide child items, press `Ctrl` + `Down` or `Ctrl` + `Up`. 16 | 17 | ## Known issues 18 | - If you have a lot of top-level items (on the order of thousands), Polymorph may struggle to load them all. Putting top-level items below subitems will increase the load speed. -------------------------------------------------------------------------------- /docs/operators_general/subframing.md: -------------------------------------------------------------------------------- 1 | # Subframing 2 | Subframing refers to when an operator contains one or more rects. It can be used to create tabs (with subframe.js), or lists of items (with stack.js). Or, as always, you can do your own thing with it. 3 | 4 | ## Sample code 5 | - operators/subframe.js 6 | - operators/stack.js [less well maintained] 7 | 8 | ## Requiremetns 9 | A subframing operator SHOULD (please): 10 | - Upon instantiating, check whether or not there are rects waiting for it in `polymorph_core.operatorLoadCallbacks[container.id]`; and append them. 11 | - Otherwise, create its own rect on startup, and as necessary. 12 | - [STANDARD] Have a method `operator.tieRect(rectID)` to replace or append a given rect. 13 | 14 | To create rects, use `new polymorph_core.rect()`. -------------------------------------------------------------------------------- /docs/operators_general/upgrade_checklist.md: -------------------------------------------------------------------------------- 1 | upgrade checklist 2 | 3 | - instantiation check out fromsavedata 4 | - itemrelevant 5 | 6 | useful anti-me regex 7 | function *\(([\w, ]*)\) *\{ 8 | ($1)=>{ 9 | 10 | update GC script 11 | 12 | - createitem 13 | - deleteitem 14 | - updateitem 15 | - focusItem 16 | - refresh 17 | - dialog -------------------------------------------------------------------------------- /docs/savesources/firebase.md: -------------------------------------------------------------------------------- 1 | ## Firebase notes 2 | 3 | Issue: limited bandwidth. 4 | Solution: get changes fibbonacilly (1,1,2,3,5,8), sorting by date_changed. Stop fetching once done. 5 | 6 | Issue: Each savesource is standalone, but we want to reduce bandwidth so we dont download the whole firebase stack, only changes. 7 | Solution: In which case, firebase is constructed so that it caches locally and then goes to FB and updates there. This also allows offline! 8 | -------------------------------------------------------------------------------- /docs/savesources/hilagit.md: -------------------------------------------------------------------------------- 1 | ## hilagit 2 | 3 | Inspired by `git`, the `hilagit` savesource attempts to solve the problem of having multiple modifications to a document occuring at once, despite `Hi`gh `La`tency. 4 | 5 | ## How it works 6 | 1. Every item is treated like a file. 7 | 2. Both the server and a client keep a local copy of the document. 8 | 3. When the client fetches the items from the server, the client checks the `_lu_` property of every item and picks the version of the item which has been updated most recently to keep. 9 | 4. When the client pushes items to the server, the client pushes a list of all its `_lu_`s. Then the server checks which of those `_lu_`s it needs to fetch from the client, and requests them from the client who sends them over. 10 | 11 | ## Improvements 12 | - The client has to send all the `_lu_`s at each save. If the client and server both know when the client last pulled, then the client can just keep track of the last pull time and doesn't have to send all the `_lu_`s. 13 | 14 | -------------------------------------------------------------------------------- /docs/savesources/monogit.md: -------------------------------------------------------------------------------- 1 | ## monogit 2 | 3 | Given the failures of the backend implementation of `hilagit`, the `monogit` save source allows large documents to be saved incrementally, reducing both bandwidth and storage requirements. 4 | 5 | ### How it works 6 | 1. At load time, the gitlite save source keeps a record of the saved status of each item. Every item starts saved. 7 | 2. When items are updated (notified through an `updateItem` event), the item is flagged as unsaved. 8 | 3. When the user presses save, the gitlite operator sends the unsaved items to a backend. 9 | 4. The backend may choose to respond with a list of items which have changed if the document is being edited by multiple individuals; and the gitlite operator will propagate those changes to the user. 10 | 11 | -------------------------------------------------------------------------------- /docs/savesources/saving.md: -------------------------------------------------------------------------------- 1 | # rationale for the save source query parameter 2 | So that links are transferrable to other users. unlike google, we can't just load everything from a single centralised source. so: always make the link shareable? If i enter the link from anywhere, if PM can fetch it it will fetch it? but i need to uniquely identify all things that can store polymorph documents, which i may not have authority for, so we'll just not for now. 3 | 4 | ## old save order 5 | 1. Load from multiple sources with fallbacks. 6 | 2. Save to all sources if possible - if not then save to as many as you can. 7 | 3. Load order shouldn't matter if we're merging, but use load order because otherwise it's too messy? 8 | 4. Load into live doc rather than load all, to save time. 9 | 10 | ## new save order 11 | 1. load from all sources that user has nominated 12 | 3. use lu to figure out which items to keep. 13 | -- 14 | 1. Fire userSave command, things which are hooked will force save if they want. 15 | 16 | # save source records 17 | `polymorph_core.userData.documents.saveSources` is an array of these. 18 | 19 | saveSourceRecord{ 20 | load:true 21 | save:true 22 | data:{ 23 | key:val 24 | } 25 | type:str 26 | } 27 | 28 | # save source instances 29 | polymorph_core now has savesourceinstances, which are instances of save sources. they are freed on resetDocument. 30 | 31 | 32 | on instantiation, if you need to load, please load. 33 | polymorph_core.integrateData(d, save_source_record.type); 34 | 35 | 36 | When making a new doc, have the option to pull from a remote server. -- instantiate a new savesource there and then. 37 | 38 | Time to make the home operator! Can only be accessed from an empty polymorph? How is it different from filescreen then? It looks prettier. 39 | 40 | so, I start doc 1 on local. I push to remote by adding a savesource. [ the savesource needs to know to get pushed to rather than to pull from. ] 41 | I start doc 2 on local2. I tell it to connect to remote and pull doc1. 42 | 43 | stack 44 | - polymorph_core.datautils.upgradeSaveData(id); 45 | 46 | 47 | if (!polymorph_core.currentDocID) { 48 | polymorph_core.datautils.upgradeSaveData(polymorph_core.currentDocID, 'lf'); 49 | } 50 | if (!polymorph_core.userData.documents[polymorph_core.currentDocID].loadHooks || Object.keys(polymorph_core.userData.documents[polymorph_core.currentDocID].loadHooks).length == 0) { 51 | polymorph_core.datautils.upgradeSaveData(polymorph_core.currentDocID, 'lf'); 52 | } 53 | 54 | - polymorph_core.fetchData(saveSourceRecord) 55 | 56 | 57 | 58 | pullFrom, pushto, etc now take instances. 59 | 60 | redo the entire dialog 61 | 62 | //just server and localforage for now. everything else can wait. -------------------------------------------------------------------------------- /docs/savesources/shenanigans/delta: -------------------------------------------------------------------------------- 1 | press load < load and save overhaul 2 | > document exists < load and save overhaul 3 | >> document has same ID as currently loaded document < store doc id with savedata 4 | >>> merge the two documents! < make merging struct, modify existing struct 5 | >>>> let user decide for each change via a dialog < polish inspector, make dialog 6 | >> document has different ID: notify and change new window 7 | > document doesnt exist: alert, do nothing 8 | 9 | 10 | 11 | Save standardisation 12 | inside box: 13 | { 14 | id:"", 15 | version: "", 16 | views:{}, 17 | items:{} 18 | } 19 | 20 | per host: 21 | { 22 | uuid: "", 23 | docs: { 24 | id: { 25 | default: 'something' 26 | saveSources:{ 27 | source: { 28 | hooked:true, 29 | data:data 30 | } 31 | } 32 | } 33 | } 34 | } 35 | 36 | load: pullAll(me.userData.documents[me.currentDoc.id].saveSources[source]) 37 | save: pushAll(me.data.docs[me.currentDoc.id].saveSources[source]) 38 | 39 | so it is possible to load another doc from a source. -------------------------------------------------------------------------------- /docs/savesources/shenanigans/links: -------------------------------------------------------------------------------- 1 | How links work 2 | 3 | item.to:{ 4 | dest:{}//not false 5 | } 6 | 7 | 8 | There is no 'from' - from can be calculated by looking at the to's on items that you care about. 9 | 10 | Undirected links are indicated by bidirected links (i.e. a->b and b->a). -------------------------------------------------------------------------------- /docs/savesources/shenanigans/options.md: -------------------------------------------------------------------------------- 1 | # options 2 | 3 | `polymorph_core.options` is a ui library for basic options. it automatically syncs the object and the input, meaning you dont have to write out annoying handler code again and again. 4 | 5 | ## where 6 | `core.js`, find `_option` 7 | 8 | ## how 9 | ```javascript 10 | new polymorph_core._option({ 11 | div: this.dialog, 12 | type: "text", 13 | object: this.settings.data, 14 | property: "saveTo", 15 | label: "Websocket server address (include ws://)", 16 | afterInput: fn(e) 17 | }) 18 | 19 | i.load() to update the option. 20 | ``` -------------------------------------------------------------------------------- /docs/savesources/shenanigans/vertical pin script: -------------------------------------------------------------------------------- 1 | core.on("updateItem",(d)=>{ 2 | let i=d.id; 3 | if (core.items[i].tracked && ( 4 | !(core.items[i].acton && core.items[i].acton.date && core.items[i].acton.date[0] && core.items[i].acton.date[0].date) || 5 | !(core.items[i].itemcluster && core.items[i].itemcluster.viewData && core.items[i].itemcluster.viewData.df90b5) 6 | )){ 7 | return; 8 | } 9 | if (core.items[i].acton && core.items[i].acton.date && core.items[i].acton.date[0] && core.items[i].acton.date[0].date){ 10 | core.items[i].itemcluster = core.items[i].itemcluster || {}; 11 | core.items[i].itemcluster.viewData = core.items[i].itemcluster.viewData || {}; 12 | core.items[i].itemcluster.viewData.df90b5 =core.items[i].itemcluster.viewData.df90b5|| {}; 13 | let relTime=(core.items[i].acton.date[0].date-Date.now())/3600000; 14 | if (relTime>2){ 15 | relTime = Math.log(relTime); 16 | }else if (relTime>0){ 17 | relTime = Math.sqrt(relTime)/2; 18 | }else if (relTime>-2){ 19 | relTime = -Math.sqrt(-relTime)/2; 20 | }else{ 21 | relTime = -Math.log(-relTime); 22 | } 23 | relTime*=200; 24 | core.items[i].itemcluster.viewData.df90b5.x=relTime; 25 | core.items[i].tracked=true; 26 | instance.log(`tracked new item ${i} with title ${core.items[i].title} from list to itemCluster`); 27 | } 28 | if (core.items[i].itemcluster && core.items[i].itemcluster.viewData && core.items[i].itemcluster.viewData.df90b5){ 29 | if (!core.items[i].acton)core.items[i].acton={datestring:{}}; 30 | core.items[i].tracked=true; 31 | instance.log(`tracked new item ${i} with title ${core.items[i].title} from itemcluster to list.`); 32 | } 33 | }); 34 | 35 | -------------------------------------------------------------------------------- /docs/user/datamodel.md: -------------------------------------------------------------------------------- 1 | # Data model 2 | Polymorph's underlying data consists of a key-value dictionary of JSON-serializable objects. This means that a polymorph document can be exported to a .json, making saving easy. Although being moddable means that theoretically these items are a free-for-all, some standards are useful for ensuring consistent operational expectations for developers; some of which are facilitated or regulated by the core. 3 | 4 | ## Client-side information 5 | Some information should be stored on the client side, including: 6 | - How the document is accessed and saved 7 | - Minor customisation options. 8 | 9 | ## Document level standards 10 | Every document has an `_meta` key and meta object, which encodes information about the document including a pointer to the base rectangle, and the container's name. 11 | 12 | ## Object level standards 13 | - Each item has a `_lu` property that states when it was last updated. 14 | - Hierarchical links are mediated by a `to:{}` dictionary, where truthy values correspond to links. Undirected links are represented by bi-directional links, i.e. `a to b` and `b to a` at the same time. This makes chasing parents somewhat difficult; so this will be managed by a cache in the core in future. 15 | 16 | ## Presentation data 17 | - Rects are stored as objects with an `_rd` property. 18 | - Operators are stored as objects with an `_od` property. Container information is stored in this key too. -------------------------------------------------------------------------------- /docs/user/keyfeats.md: -------------------------------------------------------------------------------- 1 | # Why polymorph? 2 | Polymorph is a open, heavily-customizable all-in-one knowledge management system. But what do these four concepts actually mean? 3 | 4 | ## Knowledge management system 5 | Underneath each polymorph instance is the polymorph document. A polymorph document is a list of items, which may be tasks, thoughts, or ideas. As a user, you can add, update, delete and visualise these items through a variety of forms, known as _operators_. 6 | 7 | A key tenet of polymorph is that information should be free from its mode of representation. For instance, consider a hierarchy of elements: 8 | - Vegetable 9 | - carrot 10 | - potato 11 | - Fruit 12 | - apple 13 | - peach 14 | You could represent this as bullet points, or as a graph, or you could forgo the hierarchy entirely and just have a list. However, most platforms would confine you to only one of these representations. Polymorph doesn't do that, because sometimes collections of concepts can carry different meaning when represented in different ways. 15 | 16 | To achieve this, each polymorph operator can look at the same underlying data but represent it in different ways. For example, the itemcluster operator creates a graph; whilst the workflowish operator creates a nested list. 17 | ## All-in-one 18 | To have one piece of software be able to perform the myriad of tasks that a knowledge worker (or any human for that matter) would do had been a pipe dream in the early days of software. However, in trying to create an all-in-one piece of software, a number of challenges arise: 19 | - Specialisation: Some tasks require specialised subtasks, visualisations or operations that don't present in other tasks. 20 | - Context switching: Users of an all-in-one software need to be able to switch between tasks seamlessly instead of dragging windows around everywhere 21 | These two challenges proved insurmountable for developers who could more easily focus on a single enterprise need and bathe in the value it created. Sadly, consumer software experience suffered as a result, and Polymorph was created to fill this gap (at least personally). 22 | 23 | To solve these problems, Polymorph has the following features: 24 | - Specialisation: There is still a nontrivial gain to be made by reusing common components like lists and textareas, and polymorph makes it easy to arrange these components on-the-fly to meet novel use cases or redrafts of old ones. 25 | - Context switching: Polymorph binds user interface elements in a (customisable!) hierarchy, meaning you can transition between sets of related elements instead of having to switch between multiple windows at a time. 26 | ## Heavily customizable 27 | Polymorph offers both code-level customization by providing a modular open-source system, as well as customization options for the end user using its component arrangement system. This means end users can create their own systems and are not limited to the wishes of the development team. 28 | 29 | Additionally, by separating information storage and presentation, polymorph maintains information coherence, unlike other project and knowledge management software where presentation is bound to information, meaning that upending your workflow for a more efficient one takes significantly more time. 30 | 31 | ## Open 32 | Polymorph is free, without even a sign-up wall, and offers its source for anyone who wants to take it apart. The most innovative and vibrant games are those built for modding, and Polymorph aims to be no exception. -------------------------------------------------------------------------------- /docs/user/load event timing.md: -------------------------------------------------------------------------------- 1 | # Sequence of events from load 2 | (n) means this is fired multiple times 3 | - operatorAdded(n) 4 | - UIsetup: UI is going to be setup 5 | - UIstart: UI components have been setup. 6 | - resetDocument 7 | - loadDocument 8 | -- sanitycheck 9 | -- fromsavedata 10 | - updateItem(n) 11 | - updateSettings 12 | 13 | 14 | new timing: 15 | - operatorAdded (n) 16 | - UIsetup 17 | - UIstart 18 | - resetDocument 19 | - loadDocument(source) 20 | -- getFrom(source): 21 | --- sanitycheck (the data) 22 | ---- decode 23 | ---- check if doc name is the same as expected 24 | ---- upgrade 25 | --- integrateData(the data) 26 | ---- updateItem(n) 27 | ---- core.updateSettings (? its just the _meta item) -------------------------------------------------------------------------------- /docs/user/local_machine_data.md: -------------------------------------------------------------------------------- 1 | ## Data architecture 2 | The main data repositories of Polymorph include: 3 | - polymorph_core.userData: Device (browser) scope. 4 | ```javascript 5 | polymorph_core.userData={ 6 | documents:{ 7 | document_id:{ 8 | saveSources:{ 9 | saveSourceName:savesourceData 10 | }, 11 | autosave: true/false 12 | } 13 | }, 14 | tutorialData:{ 15 | operatorName:operatorTutorialData 16 | } 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/user/overview.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Polymorph is a highly modular system, which makes it fantastic for modding. The main classes of modules outside of the care are savesources and operators: 4 | 5 | ![](https://raw.githubusercontent.com/acenturyandabit/polymorph/largeAssets/docs/polymorph_overview.PNG) 6 | 7 | - Operators operate on the data by rendering it and applying user edits to the underlying data. Operators also subscribe or publish to an event system allowing them to communicate with each other. 8 | - Save sources operate on the data by saving it to a remote location for safekeeping between sessions. 9 | 10 | There are also a number of core elements: 11 | - Containers wrap around operators to help isolate operators from each other in a field-reconfigurable manner. 12 | - Rects manage space by dividing the screen into rectangles. Each rect can either hold exactly two other rects; or an indefinite number of containers in tabs. 13 | - The core event system relays events between operators and from operators to realtime savesources. 14 | - The core document loading system reads both the local machine data and the document data to determine which save source instances and operators to create. 15 | 16 | The unit of data in polymorph is an item. An item is a plain JSON-encoded entry in the document dictionary. Items can further have properties which are then rendered by operators. 17 | 18 | 19 | [Back to contents](README.md) 20 | -------------------------------------------------------------------------------- /docs/user/rects.md: -------------------------------------------------------------------------------- 1 | # Rects 2 | 3 | ## Properties of rects 4 | These are in rect.settings, which is a getter for `polymorph_core.items[this_rect_id]._rd` 5 | - x: X or Y - if X, the children are split in the x direction; if Y, the children are split in the Y direction. 6 | - f: First or second: determines whether this child is the first or second of its pair of rects. 7 | - ps: position: the percentage left or up that the rect takes. This property is only present on the first rect; the second takes from its sibling. 8 | - s: selectedOperator: The ID of the operator that is selected. 9 | - p: parent: the ID of the parent rect. -------------------------------------------------------------------------------- /docs/user/small todos.md: -------------------------------------------------------------------------------- 1 | # Small todo's 2 | standard maybefunction filters 3 | 4 | figure out deletion, then nerf all core.on(deleteItem) 5 | 6 | nerf all toSaveData -------------------------------------------------------------------------------- /docs/user/uimodel.md: -------------------------------------------------------------------------------- 1 | # UI model 2 | Polymorph's UI model consists of nested rectangles with tabs. Lowest-level rectangles have operators which contain operators aka representations of the underlying document. 3 | - rectangle 4 | - (left) rectangle 5 | - List of items 6 | - (right) rectangle 7 | - (tab 1) Detail textarea of item 8 | - (tab 2) Calendar 9 | The rect/operator structure is stored in the data model. Much like Von Neumann's combination of opcodes and data, this model allows representations to be easily encoded, allowing data-driven representations rather than fixed representations. 10 | 11 | Between the rect and the operator is a middle layer called the Container, which creates a wrapper around the operator allowing it to be customised by the end user without asking the developer to consider the ways the end user might rewire their operator. 12 | 13 | For more specific notes on each of the different layers of the UI model, refer to the links below: 14 | - [Rects](rects.md) 15 | - [Containers](container.md) 16 | - [Operators](operators_general/overview.md) 17 | 18 | ## Subframes 19 | One gap recognised early on was that although tabs allowed a single rect to contain a single other operator, sometimes context switching required further nesting. For this reason, the subframe operator was created: 20 | - rectangle 21 | - (tab 1) Subframe: To do list context 22 | - Rectangle 23 | - (left) rectangle 24 | - List of items 25 | - (right) rectangle 26 | - (tab 1) Detail textarea of item 27 | - (tab 2) Calendar 28 | - (tab 2) Subframe: Knowledge management context 29 | - Rectangle 30 | - (left) rectangle 31 | - List of items 32 | - (right) rectangle 33 | - (tab 1) Detail textarea of item -------------------------------------------------------------------------------- /docs/user/viewdata.md: -------------------------------------------------------------------------------- 1 | Rects, operators and so on are created and call creation UPWARDS recursively. 2 | 3 | This is different to before when data was in a tree structure and so creation was done DOWNWARDS recursively. 4 | 5 | Views are Rects. They're baserects, to be precise. 6 | 7 | data used to be in a tree structure, but is now per-item so that we could manage and merge changes more easily. 8 | however, now that operators are not in a treestructure, its harder for us to manage their rendering, because we don't know which rects want which operators. 9 | 10 | To consider: 11 | - the scrollbox operator: what if there are lots of descboxes. like lots. 12 | 13 | options moving forward: 14 | - status quo: load everything at start, rects pick up orphaned operators, refresh called on focus 15 | - load everything just-in-time, always -- this is not good because e.g. background scriptrunners. 16 | 17 | keep status quo. -------------------------------------------------------------------------------- /docs/versions/unit_core.md: -------------------------------------------------------------------------------- 1 | # Unit core 2 | Polymorph has a number of core GUI features, but you may not want any of them. Perhaps you just want to take a single operator and combine it with a single save source, and be on your way. Unit-core helps you achieve this. 3 | 4 | To use unit-core, here's what you need to do: 5 | 1. Get your own web server and serve a public site with four files: 6 | - `/build/unit_core.html` -> Rename this to `index.html` or whichever in your website. 7 | - `/build/unit_core.js` 8 | - `/src/operators/[desired operator].js` -> Rename this to `operator.js` in your website. 9 | - `/src/savesources/[desired save source].js` -> Rename this to `savesource.js` in your website. 10 | 2. Edit the title in `unit_core.html` to reflect whatever subset of Polymorph you're using, or whatever you want :) 11 | 3. Start the engine using a userSave: `polymorph_core.start({})`. 12 | 13 | The usersave should allow the savesource to retrieve a well-formed polymorph document. 14 | 15 | ## Developing unit_core 16 | To debug unit_core, use a server to host the root directory of this repository, and then nagivate to `/build/unit_core.html`. Then, open a developer console, then set your unit_core to debug mode using the following commands: 17 | ```js 18 | localStorage.setItem("__unitcore_debug_operator","../src/operators/itemList.js"); 19 | localStorage.setItem("__unitcore_debug_savesource","../src/saveSources/localforage2.js"); 20 | localStorage.setItem("__unitcore_debug_from",'{"id": "unitcore_dev"}'); 21 | ``` 22 | Upon reload, this will use the files from `fileManager.js`. 23 | 24 | ## Developing operators for unit_core 25 | Checking your save source and operator core may be difficult with unit_core since you would be moving files around a lot. To assist with this, unit_core has a debug feature, where you can point unit_core at a particular save source and operator in this repository. To do this, open unit_core in your browser, and run the following lines in the console: 26 | ```js 27 | localStorage.setItem("__unitcore_debug_operator","../src/operators/.js"); 28 | localStorage.setItem("__unitcore_debug_savesource","../src/saveSources/.js"); 29 | ``` 30 | Upon reload, this will load the scripts from these locations rather than from the default path of `operator.js` and `savesource.js`. 31 | 32 | -------------------------------------------------------------------------------- /docs/workflows/common_scripting_tasks.md: -------------------------------------------------------------------------------- 1 | # Common scripting tasks 2 | 3 | 4 | ## Fixing the date of a done item 5 | E.g. You have a todo list. The todo list contains a list with items and dates. The dates can be recurring. When you delete an item off the list, you want its date to become fixed (as opposed to automatically updating, e.g. when using a TODAY clause.) 6 | 1. Create a scriptrunner. 7 | 2. Add the following code: 8 | ```js 9 | instance.on("fixdate",(e)=>{ 10 | let itm = polymorph_core.items[e.id]; 11 | let dateProperty="some_dateprop" 12 | itm[dateProperty].datestring = new Date(itm[dateProperty].date[0].date).toLocaleString() + ">" + new Date(itm[dateProperty].date[0].endDate).toLocaleString(); 13 | itm[dateProperty].date = dateParser.richExtractTime(itm[dateProperty].datestring); 14 | 15 | instance.fire("updateItem",{id: lastUpdatedItem}); 16 | instance.fire("dateUpdate"); 17 | }) 18 | ``` 19 | 3. Open the settings of the scriptrunner. 20 | 4. Attach the delete hook of another operator to the scriptrunner's `fixdate` input remap. 21 | -------------------------------------------------------------------------------- /docs/workflows/import_obj_arr_into_itemcluster.md: -------------------------------------------------------------------------------- 1 | # Importing an object array into itemcluster 2 | 3 | So, you've webscraped some data from a page and you want to make a nice visualisation in itemcluster. Great! 4 | 5 | 1. Create a polymorph document, add the itemcluster operator. 6 | 2. Clean the data so that it is an array of object with a title property equal to the text to be displayed. 7 | 3. Click preferences > output to text, paste in json data 8 | TO IMPLEMENT 9 | 4. Find itemcluster's operator ID. paste it in the "operator to create" box 10 | 5. Click "Create in operator", 11 | 6. also click "hash by title property" to allow updating later down the track. -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Polymorph 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | 20 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "PM", 3 | "name": "Polymorph", 4 | "icons": [ 5 | { 6 | "src": "assets/icon-192.png", 7 | "type": "image/png", 8 | "sizes": "192x192" 9 | } 10 | ], 11 | "start_url": "/", 12 | "background_color": "#3367D6", 13 | "display": "standalone", 14 | "scope": "/", 15 | "theme_color": "#3367D6" 16 | } -------------------------------------------------------------------------------- /src/3pt/Treant.css: -------------------------------------------------------------------------------- 1 | /* required LIB STYLES */ 2 | /* .Treant se automatski dodaje na svaki chart conatiner */ 3 | .Treant { position: relative; overflow: hidden; padding: 0 !important; } 4 | .Treant > .node, 5 | .Treant > .pseudo { position: absolute; display: block; visibility: hidden; } 6 | .Treant.Treant-loaded .node, 7 | .Treant.Treant-loaded .pseudo { visibility: visible; } 8 | .Treant > .pseudo { width: 0; height: 0; border: none; padding: 0; } 9 | .Treant .collapse-switch { width: 3px; height: 3px; display: block; border: 1px solid black; position: absolute; top: 1px; right: 1px; cursor: pointer; } 10 | .Treant .collapsed .collapse-switch { background-color: #868DEE; } 11 | .Treant > .node img { border: none; float: left; } -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/af.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.af = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var af = { 8 | code: "af", 9 | week: { 10 | dow: 1, 11 | doy: 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. 12 | }, 13 | buttonText: { 14 | prev: "Vorige", 15 | next: "Volgende", 16 | today: "Vandag", 17 | year: "Jaar", 18 | month: "Maand", 19 | week: "Week", 20 | day: "Dag", 21 | list: "Agenda" 22 | }, 23 | allDayHtml: "Heeldag", 24 | eventLimitText: "Addisionele", 25 | noEventsMessage: "Daar is geen gebeurtenisse nie" 26 | }; 27 | 28 | return af; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ar-dz.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-dz'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var arDz = { 8 | code: "ar-dz", 9 | week: { 10 | dow: 0, 11 | doy: 4 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | dir: 'rtl', 14 | buttonText: { 15 | prev: "السابق", 16 | next: "التالي", 17 | today: "اليوم", 18 | month: "شهر", 19 | week: "أسبوع", 20 | day: "يوم", 21 | list: "أجندة" 22 | }, 23 | weekLabel: "أسبوع", 24 | allDayText: "اليوم كله", 25 | eventLimitText: "أخرى", 26 | noEventsMessage: "أي أحداث لعرض" 27 | }; 28 | 29 | return arDz; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ar-kw.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-kw'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var arKw = { 8 | code: "ar-kw", 9 | week: { 10 | dow: 0, 11 | doy: 12 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | dir: 'rtl', 14 | buttonText: { 15 | prev: "السابق", 16 | next: "التالي", 17 | today: "اليوم", 18 | month: "شهر", 19 | week: "أسبوع", 20 | day: "يوم", 21 | list: "أجندة" 22 | }, 23 | weekLabel: "أسبوع", 24 | allDayText: "اليوم كله", 25 | eventLimitText: "أخرى", 26 | noEventsMessage: "أي أحداث لعرض" 27 | }; 28 | 29 | return arKw; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ar-ly.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-ly'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var arLy = { 8 | code: "ar-ly", 9 | week: { 10 | dow: 6, 11 | doy: 12 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | dir: 'rtl', 14 | buttonText: { 15 | prev: "السابق", 16 | next: "التالي", 17 | today: "اليوم", 18 | month: "شهر", 19 | week: "أسبوع", 20 | day: "يوم", 21 | list: "أجندة" 22 | }, 23 | weekLabel: "أسبوع", 24 | allDayText: "اليوم كله", 25 | eventLimitText: "أخرى", 26 | noEventsMessage: "أي أحداث لعرض" 27 | }; 28 | 29 | return arLy; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ar-ma.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-ma'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var arMa = { 8 | code: "ar-ma", 9 | week: { 10 | dow: 6, 11 | doy: 12 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | dir: 'rtl', 14 | buttonText: { 15 | prev: "السابق", 16 | next: "التالي", 17 | today: "اليوم", 18 | month: "شهر", 19 | week: "أسبوع", 20 | day: "يوم", 21 | list: "أجندة" 22 | }, 23 | weekLabel: "أسبوع", 24 | allDayText: "اليوم كله", 25 | eventLimitText: "أخرى", 26 | noEventsMessage: "أي أحداث لعرض" 27 | }; 28 | 29 | return arMa; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ar-sa.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-sa'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var arSa = { 8 | code: "ar-sa", 9 | week: { 10 | dow: 0, 11 | doy: 6 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | dir: 'rtl', 14 | buttonText: { 15 | prev: "السابق", 16 | next: "التالي", 17 | today: "اليوم", 18 | month: "شهر", 19 | week: "أسبوع", 20 | day: "يوم", 21 | list: "أجندة" 22 | }, 23 | weekLabel: "أسبوع", 24 | allDayText: "اليوم كله", 25 | eventLimitText: "أخرى", 26 | noEventsMessage: "أي أحداث لعرض" 27 | }; 28 | 29 | return arSa; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ar-tn.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['ar-tn'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var arTn = { 8 | code: "ar-tn", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | dir: 'rtl', 14 | buttonText: { 15 | prev: "السابق", 16 | next: "التالي", 17 | today: "اليوم", 18 | month: "شهر", 19 | week: "أسبوع", 20 | day: "يوم", 21 | list: "أجندة" 22 | }, 23 | weekLabel: "أسبوع", 24 | allDayText: "اليوم كله", 25 | eventLimitText: "أخرى", 26 | noEventsMessage: "أي أحداث لعرض" 27 | }; 28 | 29 | return arTn; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ar.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ar = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ar = { 8 | code: "ar", 9 | week: { 10 | dow: 6, 11 | doy: 12 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | dir: 'rtl', 14 | buttonText: { 15 | prev: "السابق", 16 | next: "التالي", 17 | today: "اليوم", 18 | month: "شهر", 19 | week: "أسبوع", 20 | day: "يوم", 21 | list: "أجندة" 22 | }, 23 | weekLabel: "أسبوع", 24 | allDayText: "اليوم كله", 25 | eventLimitText: "أخرى", 26 | noEventsMessage: "أي أحداث لعرض" 27 | }; 28 | 29 | return ar; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/bg.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.bg = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var bg = { 8 | code: "bg", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "назад", 15 | next: "напред", 16 | today: "днес", 17 | month: "Месец", 18 | week: "Седмица", 19 | day: "Ден", 20 | list: "График" 21 | }, 22 | allDayText: "Цял ден", 23 | eventLimitText: function (n) { 24 | return "+още " + n; 25 | }, 26 | noEventsMessage: "Няма събития за показване" 27 | }; 28 | 29 | return bg; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/bs.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.bs = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var bs = { 8 | code: "bs", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Prošli", 15 | next: "Sljedeći", 16 | today: "Danas", 17 | month: "Mjesec", 18 | week: "Sedmica", 19 | day: "Dan", 20 | list: "Raspored" 21 | }, 22 | weekLabel: "Sed", 23 | allDayText: "Cijeli dan", 24 | eventLimitText: function (n) { 25 | return "+ još " + n; 26 | }, 27 | noEventsMessage: "Nema događaja za prikazivanje" 28 | }; 29 | 30 | return bs; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ca.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ca = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ca = { 8 | code: "ca", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Anterior", 15 | next: "Següent", 16 | today: "Avui", 17 | month: "Mes", 18 | week: "Setmana", 19 | day: "Dia", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Set", 23 | allDayText: "Tot el dia", 24 | eventLimitText: "més", 25 | noEventsMessage: "No hi ha esdeveniments per mostrar" 26 | }; 27 | 28 | return ca; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/cs.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.cs = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var cs = { 8 | code: "cs", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Dříve", 15 | next: "Později", 16 | today: "Nyní", 17 | month: "Měsíc", 18 | week: "Týden", 19 | day: "Den", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Týd", 23 | allDayText: "Celý den", 24 | eventLimitText: function (n) { 25 | return "+další: " + n; 26 | }, 27 | noEventsMessage: "Žádné akce k zobrazení" 28 | }; 29 | 30 | return cs; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/da.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.da = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var da = { 8 | code: "da", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Forrige", 15 | next: "Næste", 16 | today: "Idag", 17 | month: "Måned", 18 | week: "Uge", 19 | day: "Dag", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Uge", 23 | allDayText: "Hele dagen", 24 | eventLimitText: "flere", 25 | noEventsMessage: "Ingen arrangementer at vise" 26 | }; 27 | 28 | return da; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/de.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.de = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var de = { 8 | code: "de", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Zurück", 15 | next: "Vor", 16 | today: "Heute", 17 | year: "Jahr", 18 | month: "Monat", 19 | week: "Woche", 20 | day: "Tag", 21 | list: "Terminübersicht" 22 | }, 23 | weekLabel: "KW", 24 | allDayText: "Ganztägig", 25 | eventLimitText: function (n) { 26 | return "+ weitere " + n; 27 | }, 28 | noEventsMessage: "Keine Ereignisse anzuzeigen" 29 | }; 30 | 31 | return de; 32 | 33 | })); 34 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/el.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.el = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var el = { 8 | code: "el", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Προηγούμενος", 15 | next: "Επόμενος", 16 | today: "Σήμερα", 17 | month: "Μήνας", 18 | week: "Εβδομάδα", 19 | day: "Ημέρα", 20 | list: "Ατζέντα" 21 | }, 22 | weekLabel: "Εβδ", 23 | allDayText: "Ολοήμερο", 24 | eventLimitText: "περισσότερα", 25 | noEventsMessage: "Δεν υπάρχουν γεγονότα για να εμφανιστεί" 26 | }; 27 | 28 | return el; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/en-au.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['en-au'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var enAu = { 8 | code: "en-au", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | } 13 | }; 14 | 15 | return enAu; 16 | 17 | })); 18 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/en-gb.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['en-gb'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var enGb = { 8 | code: "en-gb", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | } 13 | }; 14 | 15 | return enGb; 16 | 17 | })); 18 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/en-nz.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['en-nz'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var enNz = { 8 | code: "en-nz", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | } 13 | }; 14 | 15 | return enNz; 16 | 17 | })); 18 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/es-us.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['es-us'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var esUs = { 8 | code: "es", 9 | week: { 10 | dow: 0, 11 | doy: 6 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Ant", 15 | next: "Sig", 16 | today: "Hoy", 17 | month: "Mes", 18 | week: "Semana", 19 | day: "Día", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Sm", 23 | allDayHtml: "Todo
el día", 24 | eventLimitText: "más", 25 | noEventsMessage: "No hay eventos para mostrar" 26 | }; 27 | 28 | return esUs; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/es.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.es = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var es = { 8 | code: "es", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Ant", 15 | next: "Sig", 16 | today: "Hoy", 17 | month: "Mes", 18 | week: "Semana", 19 | day: "Día", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Sm", 23 | allDayHtml: "Todo
el día", 24 | eventLimitText: "más", 25 | noEventsMessage: "No hay eventos para mostrar" 26 | }; 27 | 28 | return es; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/et.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.et = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var et = { 8 | code: "et", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Eelnev", 15 | next: "Järgnev", 16 | today: "Täna", 17 | month: "Kuu", 18 | week: "Nädal", 19 | day: "Päev", 20 | list: "Päevakord" 21 | }, 22 | weekLabel: "näd", 23 | allDayText: "Kogu päev", 24 | eventLimitText: function (n) { 25 | return "+ veel " + n; 26 | }, 27 | noEventsMessage: "Kuvamiseks puuduvad sündmused" 28 | }; 29 | 30 | return et; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/eu.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.eu = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var eu = { 8 | code: "eu", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Aur", 15 | next: "Hur", 16 | today: "Gaur", 17 | month: "Hilabetea", 18 | week: "Astea", 19 | day: "Eguna", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "As", 23 | allDayHtml: "Egun
osoa", 24 | eventLimitText: "gehiago", 25 | noEventsMessage: "Ez dago ekitaldirik erakusteko" 26 | }; 27 | 28 | return eu; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/fa.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.fa = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var fa = { 8 | code: "fa", 9 | week: { 10 | dow: 6, 11 | doy: 12 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | dir: 'rtl', 14 | buttonText: { 15 | prev: "قبلی", 16 | next: "بعدی", 17 | today: "امروز", 18 | month: "ماه", 19 | week: "هفته", 20 | day: "روز", 21 | list: "برنامه" 22 | }, 23 | weekLabel: "هف", 24 | allDayText: "تمام روز", 25 | eventLimitText: function (n) { 26 | return "بیش از " + n; 27 | }, 28 | noEventsMessage: "هیچ رویدادی به نمایش" 29 | }; 30 | 31 | return fa; 32 | 33 | })); 34 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/fi.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.fi = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var fi = { 8 | code: "fi", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Edellinen", 15 | next: "Seuraava", 16 | today: "Tänään", 17 | month: "Kuukausi", 18 | week: "Viikko", 19 | day: "Päivä", 20 | list: "Tapahtumat" 21 | }, 22 | weekLabel: "Vk", 23 | allDayText: "Koko päivä", 24 | eventLimitText: "lisää", 25 | noEventsMessage: "Ei näytettäviä tapahtumia" 26 | }; 27 | 28 | return fi; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/fr-ca.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['fr-ca'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var frCa = { 8 | code: "fr", 9 | buttonText: { 10 | prev: "Précédent", 11 | next: "Suivant", 12 | today: "Aujourd'hui", 13 | year: "Année", 14 | month: "Mois", 15 | week: "Semaine", 16 | day: "Jour", 17 | list: "Mon planning" 18 | }, 19 | weekLabel: "Sem.", 20 | allDayHtml: "Toute la
journée", 21 | eventLimitText: "en plus", 22 | noEventsMessage: "Aucun événement à afficher" 23 | }; 24 | 25 | return frCa; 26 | 27 | })); 28 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/fr-ch.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['fr-ch'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var frCh = { 8 | code: "fr-ch", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Précédent", 15 | next: "Suivant", 16 | today: "Courant", 17 | year: "Année", 18 | month: "Mois", 19 | week: "Semaine", 20 | day: "Jour", 21 | list: "Mon planning" 22 | }, 23 | weekLabel: "Sm", 24 | allDayHtml: "Toute la
journée", 25 | eventLimitText: "en plus", 26 | noEventsMessage: "Aucun événement à afficher" 27 | }; 28 | 29 | return frCh; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/fr.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.fr = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var fr = { 8 | code: "fr", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Précédent", 15 | next: "Suivant", 16 | today: "Aujourd'hui", 17 | year: "Année", 18 | month: "Mois", 19 | week: "Semaine", 20 | day: "Jour", 21 | list: "Mon planning" 22 | }, 23 | weekLabel: "Sem.", 24 | allDayHtml: "Toute la
journée", 25 | eventLimitText: "en plus", 26 | noEventsMessage: "Aucun événement à afficher" 27 | }; 28 | 29 | return fr; 30 | 31 | })); 32 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/gl.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.gl = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var gl = { 8 | code: "gl", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Ant", 15 | next: "Seg", 16 | today: "Hoxe", 17 | month: "Mes", 18 | week: "Semana", 19 | day: "Día", 20 | list: "Axenda" 21 | }, 22 | weekLabel: "Sm", 23 | allDayHtml: "Todo
o día", 24 | eventLimitText: "máis", 25 | noEventsMessage: "Non hai eventos para amosar" 26 | }; 27 | 28 | return gl; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/he.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.he = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var he = { 8 | code: "he", 9 | dir: 'rtl', 10 | buttonText: { 11 | prev: "הקודם", 12 | next: "הבא", 13 | today: "היום", 14 | month: "חודש", 15 | week: "שבוע", 16 | day: "יום", 17 | list: "סדר יום" 18 | }, 19 | allDayText: "כל היום", 20 | eventLimitText: "אחר", 21 | noEventsMessage: "אין אירועים להצגה", 22 | weekLabel: "שבוע" 23 | }; 24 | 25 | return he; 26 | 27 | })); 28 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/hi.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.hi = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var hi = { 8 | code: "hi", 9 | week: { 10 | dow: 0, 11 | doy: 6 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "पिछला", 15 | next: "अगला", 16 | today: "आज", 17 | month: "महीना", 18 | week: "सप्ताह", 19 | day: "दिन", 20 | list: "कार्यसूची" 21 | }, 22 | weekLabel: "हफ्ता", 23 | allDayText: "सभी दिन", 24 | eventLimitText: function (n) { 25 | return "+अधिक " + n; 26 | }, 27 | noEventsMessage: "कोई घटनाओं को प्रदर्शित करने के लिए" 28 | }; 29 | 30 | return hi; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/hr.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.hr = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var hr = { 8 | code: "hr", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Prijašnji", 15 | next: "Sljedeći", 16 | today: "Danas", 17 | month: "Mjesec", 18 | week: "Tjedan", 19 | day: "Dan", 20 | list: "Raspored" 21 | }, 22 | weekLabel: "Tje", 23 | allDayText: "Cijeli dan", 24 | eventLimitText: function (n) { 25 | return "+ još " + n; 26 | }, 27 | noEventsMessage: "Nema događaja za prikaz" 28 | }; 29 | 30 | return hr; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/hu.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.hu = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var hu = { 8 | code: "hu", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "vissza", 15 | next: "előre", 16 | today: "ma", 17 | month: "Hónap", 18 | week: "Hét", 19 | day: "Nap", 20 | list: "Napló" 21 | }, 22 | weekLabel: "Hét", 23 | allDayText: "Egész nap", 24 | eventLimitText: "további", 25 | noEventsMessage: "Nincs megjeleníthető esemény" 26 | }; 27 | 28 | return hu; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/id.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.id = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var id = { 8 | code: "id", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "mundur", 15 | next: "maju", 16 | today: "hari ini", 17 | month: "Bulan", 18 | week: "Minggu", 19 | day: "Hari", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Mg", 23 | allDayHtml: "Sehari
penuh", 24 | eventLimitText: "lebih", 25 | noEventsMessage: "Tidak ada acara untuk ditampilkan" 26 | }; 27 | 28 | return id; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/is.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.is = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var is = { 8 | code: "is", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Fyrri", 15 | next: "Næsti", 16 | today: "Í dag", 17 | month: "Mánuður", 18 | week: "Vika", 19 | day: "Dagur", 20 | list: "Dagskrá" 21 | }, 22 | weekLabel: "Vika", 23 | allDayHtml: "Allan
daginn", 24 | eventLimitText: "meira", 25 | noEventsMessage: "Engir viðburðir til að sýna" 26 | }; 27 | 28 | return is; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/it.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.it = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var it = { 8 | code: "it", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Prec", 15 | next: "Succ", 16 | today: "Oggi", 17 | month: "Mese", 18 | week: "Settimana", 19 | day: "Giorno", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Sm", 23 | allDayHtml: "Tutto il
giorno", 24 | eventLimitText: function (n) { 25 | return "+altri " + n; 26 | }, 27 | noEventsMessage: "Non ci sono eventi da visualizzare" 28 | }; 29 | 30 | return it; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ja.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ja = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ja = { 8 | code: "ja", 9 | buttonText: { 10 | prev: "前", 11 | next: "次", 12 | today: "今日", 13 | month: "月", 14 | week: "週", 15 | day: "日", 16 | list: "予定リスト" 17 | }, 18 | weekLabel: "週", 19 | allDayText: "終日", 20 | eventLimitText: function (n) { 21 | return "他 " + n + " 件"; 22 | }, 23 | noEventsMessage: "表示する予定はありません" 24 | }; 25 | 26 | return ja; 27 | 28 | })); 29 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ka.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ka = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ka = { 8 | code: "ka", 9 | week: { 10 | dow: 1, 11 | doy: 7 12 | }, 13 | buttonText: { 14 | prev: "წინა", 15 | next: "შემდეგი", 16 | today: "დღეს", 17 | month: "თვე", 18 | week: "კვირა", 19 | day: "დღე", 20 | list: "დღის წესრიგი" 21 | }, 22 | weekLabel: "კვ", 23 | allDayText: "მთელი დღე", 24 | eventLimitText: function (n) { 25 | return "+ კიდევ " + n; 26 | }, 27 | noEventsMessage: "ღონისძიებები არ არის" 28 | }; 29 | 30 | return ka; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/kk.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.kk = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var kk = { 8 | code: "kk", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Алдыңғы", 15 | next: "Келесі", 16 | today: "Бүгін", 17 | month: "Ай", 18 | week: "Апта", 19 | day: "Күн", 20 | list: "Күн тәртібі" 21 | }, 22 | weekLabel: "Не", 23 | allDayText: "Күні бойы", 24 | eventLimitText: function (n) { 25 | return "+ тағы " + n; 26 | }, 27 | noEventsMessage: "Көрсету үшін оқиғалар жоқ" 28 | }; 29 | 30 | return kk; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ko.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ko = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ko = { 8 | code: "ko", 9 | buttonText: { 10 | prev: "이전달", 11 | next: "다음달", 12 | today: "오늘", 13 | month: "월", 14 | week: "주", 15 | day: "일", 16 | list: "일정목록" 17 | }, 18 | weekLabel: "주", 19 | allDayText: "종일", 20 | eventLimitText: "개", 21 | noEventsMessage: "일정이 없습니다" 22 | }; 23 | 24 | return ko; 25 | 26 | })); 27 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/lb.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.lb = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var lb = { 8 | code: "lb", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Zréck", 15 | next: "Weider", 16 | today: "Haut", 17 | month: "Mount", 18 | week: "Woch", 19 | day: "Dag", 20 | list: "Terminiwwersiicht" 21 | }, 22 | weekLabel: "W", 23 | allDayText: "Ganzen Dag", 24 | eventLimitText: "méi", 25 | noEventsMessage: "Nee Evenementer ze affichéieren" 26 | }; 27 | 28 | return lb; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/lt.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.lt = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var lt = { 8 | code: "lt", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Atgal", 15 | next: "Pirmyn", 16 | today: "Šiandien", 17 | month: "Mėnuo", 18 | week: "Savaitė", 19 | day: "Diena", 20 | list: "Darbotvarkė" 21 | }, 22 | weekLabel: "SAV", 23 | allDayText: "Visą dieną", 24 | eventLimitText: "daugiau", 25 | noEventsMessage: "Nėra įvykių rodyti" 26 | }; 27 | 28 | return lt; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/lv.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.lv = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var lv = { 8 | code: "lv", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Iepr.", 15 | next: "Nāk.", 16 | today: "Šodien", 17 | month: "Mēnesis", 18 | week: "Nedēļa", 19 | day: "Diena", 20 | list: "Dienas kārtība" 21 | }, 22 | weekLabel: "Ned.", 23 | allDayText: "Visu dienu", 24 | eventLimitText: function (n) { 25 | return "+vēl " + n; 26 | }, 27 | noEventsMessage: "Nav notikumu" 28 | }; 29 | 30 | return lv; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/mk.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.mk = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var mk = { 8 | code: "mk", 9 | buttonText: { 10 | prev: "претходно", 11 | next: "следно", 12 | today: "Денес", 13 | month: "Месец", 14 | week: "Недела", 15 | day: "Ден", 16 | list: "График" 17 | }, 18 | weekLabel: "Сед", 19 | allDayText: "Цел ден", 20 | eventLimitText: function (n) { 21 | return "+повеќе " + n; 22 | }, 23 | noEventsMessage: "Нема настани за прикажување" 24 | }; 25 | 26 | return mk; 27 | 28 | })); 29 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ms.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ms = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ms = { 8 | code: "ms", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Sebelum", 15 | next: "Selepas", 16 | today: "hari ini", 17 | month: "Bulan", 18 | week: "Minggu", 19 | day: "Hari", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Mg", 23 | allDayText: "Sepanjang hari", 24 | eventLimitText: function (n) { 25 | return "masih ada " + n + " acara"; 26 | }, 27 | noEventsMessage: "Tiada peristiwa untuk dipaparkan" 28 | }; 29 | 30 | return ms; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/nb.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.nb = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var nb = { 8 | code: "nb", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Forrige", 15 | next: "Neste", 16 | today: "I dag", 17 | month: "Måned", 18 | week: "Uke", 19 | day: "Dag", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Uke", 23 | allDayText: "Hele dagen", 24 | eventLimitText: "til", 25 | noEventsMessage: "Ingen hendelser å vise" 26 | }; 27 | 28 | return nb; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/nl.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.nl = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var nl = { 8 | code: "nl", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Voorgaand", 15 | next: "Volgende", 16 | today: "Vandaag", 17 | year: "Jaar", 18 | month: "Maand", 19 | week: "Week", 20 | day: "Dag", 21 | list: "Agenda" 22 | }, 23 | allDayText: "Hele dag", 24 | eventLimitText: "extra", 25 | noEventsMessage: "Geen evenementen om te laten zien" 26 | }; 27 | 28 | return nl; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/nn.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.nn = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var nn = { 8 | code: "nn", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Førre", 15 | next: "Neste", 16 | today: "I dag", 17 | month: "Månad", 18 | week: "Veke", 19 | day: "Dag", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Veke", 23 | allDayText: "Heile dagen", 24 | eventLimitText: "til", 25 | noEventsMessage: "Ingen hendelser å vise" 26 | }; 27 | 28 | return nn; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/pl.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.pl = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var pl = { 8 | code: "pl", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Poprzedni", 15 | next: "Następny", 16 | today: "Dziś", 17 | month: "Miesiąc", 18 | week: "Tydzień", 19 | day: "Dzień", 20 | list: "Plan dnia" 21 | }, 22 | weekLabel: "Tydz", 23 | allDayText: "Cały dzień", 24 | eventLimitText: "więcej", 25 | noEventsMessage: "Brak wydarzeń do wyświetlenia" 26 | }; 27 | 28 | return pl; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/pt-br.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['pt-br'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ptBr = { 8 | code: "pt-br", 9 | buttonText: { 10 | prev: "Anterior", 11 | next: "Próximo", 12 | today: "Hoje", 13 | month: "Mês", 14 | week: "Semana", 15 | day: "Dia", 16 | list: "Compromissos" 17 | }, 18 | weekLabel: "Sm", 19 | allDayText: "dia inteiro", 20 | eventLimitText: function (n) { 21 | return "mais +" + n; 22 | }, 23 | noEventsMessage: "Não há eventos para mostrar" 24 | }; 25 | 26 | return ptBr; 27 | 28 | })); 29 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/pt.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.pt = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var pt = { 8 | code: "pt", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Anterior", 15 | next: "Seguinte", 16 | today: "Hoje", 17 | month: "Mês", 18 | week: "Semana", 19 | day: "Dia", 20 | list: "Agenda" 21 | }, 22 | weekLabel: "Sem", 23 | allDayText: "Todo o dia", 24 | eventLimitText: "mais", 25 | noEventsMessage: "Não há eventos para mostrar" 26 | }; 27 | 28 | return pt; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ro.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ro = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ro = { 8 | code: "ro", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "precedentă", 15 | next: "următoare", 16 | today: "Azi", 17 | month: "Lună", 18 | week: "Săptămână", 19 | day: "Zi", 20 | list: "Agendă" 21 | }, 22 | weekLabel: "Săpt", 23 | allDayText: "Toată ziua", 24 | eventLimitText: function (n) { 25 | return "+alte " + n; 26 | }, 27 | noEventsMessage: "Nu există evenimente de afișat" 28 | }; 29 | 30 | return ro; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/ru.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.ru = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var ru = { 8 | code: "ru", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Пред", 15 | next: "След", 16 | today: "Сегодня", 17 | month: "Месяц", 18 | week: "Неделя", 19 | day: "День", 20 | list: "Повестка дня" 21 | }, 22 | weekLabel: "Нед", 23 | allDayText: "Весь день", 24 | eventLimitText: function (n) { 25 | return "+ ещё " + n; 26 | }, 27 | noEventsMessage: "Нет событий для отображения" 28 | }; 29 | 30 | return ru; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/sk.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sk = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var sk = { 8 | code: "sk", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Predchádzajúci", 15 | next: "Nasledujúci", 16 | today: "Dnes", 17 | month: "Mesiac", 18 | week: "Týždeň", 19 | day: "Deň", 20 | list: "Rozvrh" 21 | }, 22 | weekLabel: "Ty", 23 | allDayText: "Celý deň", 24 | eventLimitText: function (n) { 25 | return "+ďalšie: " + n; 26 | }, 27 | noEventsMessage: "Žiadne akcie na zobrazenie" 28 | }; 29 | 30 | return sk; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/sl.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sl = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var sl = { 8 | code: "sl", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Prejšnji", 15 | next: "Naslednji", 16 | today: "Trenutni", 17 | month: "Mesec", 18 | week: "Teden", 19 | day: "Dan", 20 | list: "Dnevni red" 21 | }, 22 | weekLabel: "Teden", 23 | allDayText: "Ves dan", 24 | eventLimitText: "več", 25 | noEventsMessage: "Ni dogodkov za prikaz" 26 | }; 27 | 28 | return sl; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/sq.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sq = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var sq = { 8 | code: "sq", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "mbrapa", 15 | next: "Përpara", 16 | today: "sot", 17 | month: "Muaj", 18 | week: "Javë", 19 | day: "Ditë", 20 | list: "Listë" 21 | }, 22 | weekLabel: "Ja", 23 | allDayHtml: "Gjithë
ditën", 24 | eventLimitText: function (n) { 25 | return "+më tepër " + n; 26 | }, 27 | noEventsMessage: "Nuk ka evente për të shfaqur" 28 | }; 29 | 30 | return sq; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/sr-cyrl.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['sr-cyrl'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var srCyrl = { 8 | code: "sr-cyrl", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Претходна", 15 | next: "следећи", 16 | today: "Данас", 17 | month: "Месец", 18 | week: "Недеља", 19 | day: "Дан", 20 | list: "Планер" 21 | }, 22 | weekLabel: "Сед", 23 | allDayText: "Цео дан", 24 | eventLimitText: function (n) { 25 | return "+ још " + n; 26 | }, 27 | noEventsMessage: "Нема догађаја за приказ" 28 | }; 29 | 30 | return srCyrl; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/sr.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sr = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var sr = { 8 | code: "sr", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Prethodna", 15 | next: "Sledeći", 16 | today: "Danas", 17 | month: "Mеsеc", 18 | week: "Nеdеlja", 19 | day: "Dan", 20 | list: "Planеr" 21 | }, 22 | weekLabel: "Sed", 23 | allDayText: "Cеo dan", 24 | eventLimitText: function (n) { 25 | return "+ još " + n; 26 | }, 27 | noEventsMessage: "Nеma događaja za prikaz" 28 | }; 29 | 30 | return sr; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/sv.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.sv = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var sv = { 8 | code: "sv", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Förra", 15 | next: "Nästa", 16 | today: "Idag", 17 | month: "Månad", 18 | week: "Vecka", 19 | day: "Dag", 20 | list: "Program" 21 | }, 22 | weekLabel: "v.", 23 | allDayText: "Heldag", 24 | eventLimitText: "till", 25 | noEventsMessage: "Inga händelser att visa" 26 | }; 27 | 28 | return sv; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/th.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.th = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var th = { 8 | code: "th", 9 | buttonText: { 10 | prev: "ย้อน", 11 | next: "ถัดไป", 12 | today: "วันนี้", 13 | month: "เดือน", 14 | week: "สัปดาห์", 15 | day: "วัน", 16 | list: "แผนงาน" 17 | }, 18 | allDayText: "ตลอดวัน", 19 | eventLimitText: "เพิ่มเติม", 20 | noEventsMessage: "ไม่มีกิจกรรมที่จะแสดง" 21 | }; 22 | 23 | return th; 24 | 25 | })); 26 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/tr.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.tr = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var tr = { 8 | code: "tr", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "geri", 15 | next: "ileri", 16 | today: "bugün", 17 | month: "Ay", 18 | week: "Hafta", 19 | day: "Gün", 20 | list: "Ajanda" 21 | }, 22 | weekLabel: "Hf", 23 | allDayText: "Tüm gün", 24 | eventLimitText: "daha fazla", 25 | noEventsMessage: "Gösterilecek etkinlik yok" 26 | }; 27 | 28 | return tr; 29 | 30 | })); 31 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/uk.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.uk = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var uk = { 8 | code: "uk", 9 | week: { 10 | dow: 1, 11 | doy: 7 // The week that contains Jan 1st is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Попередній", 15 | next: "далі", 16 | today: "Сьогодні", 17 | month: "Місяць", 18 | week: "Тиждень", 19 | day: "День", 20 | list: "Порядок денний" 21 | }, 22 | weekLabel: "Тиж", 23 | allDayText: "Увесь день", 24 | eventLimitText: function (n) { 25 | return "+ще " + n + "..."; 26 | }, 27 | noEventsMessage: "Немає подій для відображення" 28 | }; 29 | 30 | return uk; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/vi.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales.vi = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var vi = { 8 | code: "vi", 9 | week: { 10 | dow: 1, 11 | doy: 4 // The week that contains Jan 4th is the first week of the year. 12 | }, 13 | buttonText: { 14 | prev: "Trước", 15 | next: "Tiếp", 16 | today: "Hôm nay", 17 | month: "Tháng", 18 | week: "Tuần", 19 | day: "Ngày", 20 | list: "Lịch biểu" 21 | }, 22 | weekLabel: "Tu", 23 | allDayText: "Cả ngày", 24 | eventLimitText: function (n) { 25 | return "+ thêm " + n; 26 | }, 27 | noEventsMessage: "Không có sự kiện để hiển thị" 28 | }; 29 | 30 | return vi; 31 | 32 | })); 33 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/zh-cn.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['zh-cn'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var zhCn = { 8 | code: "zh-cn", 9 | week: { 10 | // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 11 | dow: 1, 12 | doy: 4 // The week that contains Jan 4th is the first week of the year. 13 | }, 14 | buttonText: { 15 | prev: "上月", 16 | next: "下月", 17 | today: "今天", 18 | month: "月", 19 | week: "周", 20 | day: "日", 21 | list: "日程" 22 | }, 23 | weekLabel: "周", 24 | allDayText: "全天", 25 | eventLimitText: function (n) { 26 | return "另外 " + n + " 个"; 27 | }, 28 | noEventsMessage: "没有事件显示" 29 | }; 30 | 31 | return zhCn; 32 | 33 | })); 34 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/core/locales/zh-tw.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global = global || self, (global.FullCalendarLocales = global.FullCalendarLocales || {}, global.FullCalendarLocales['zh-tw'] = factory())); 5 | }(this, function () { 'use strict'; 6 | 7 | var zhTw = { 8 | code: "zh-tw", 9 | buttonText: { 10 | prev: "上月", 11 | next: "下月", 12 | today: "今天", 13 | month: "月", 14 | week: "週", 15 | day: "天", 16 | list: "活動列表" 17 | }, 18 | weekLabel: "周", 19 | allDayText: "整天", 20 | eventLimitText: '顯示更多', 21 | noEventsMessage: "没有任何活動" 22 | }; 23 | 24 | return zhTw; 25 | 26 | })); 27 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/daygrid/main.css: -------------------------------------------------------------------------------- 1 | /*! 2 | FullCalendar Day Grid Plugin v4.2.0 3 | Docs & License: https://fullcalendar.io/ 4 | (c) 2019 Adam Shaw 5 | */ 6 | /* DayGridView 7 | --------------------------------------------------------------------------------------------------*/ 8 | /* day row structure */ 9 | .fc-dayGridWeek-view .fc-content-skeleton, 10 | .fc-dayGridDay-view .fc-content-skeleton { 11 | /* there may be week numbers in these views, so no padding-top */ 12 | padding-bottom: 1em; 13 | /* ensure a space at bottom of cell for user selecting/clicking */ } 14 | 15 | .fc-dayGrid-view .fc-body .fc-row { 16 | min-height: 4em; 17 | /* ensure that all rows are at least this tall */ } 18 | 19 | /* a "rigid" row will take up a constant amount of height because content-skeleton is absolute */ 20 | .fc-row.fc-rigid { 21 | overflow: hidden; } 22 | 23 | .fc-row.fc-rigid .fc-content-skeleton { 24 | position: absolute; 25 | top: 0; 26 | left: 0; 27 | right: 0; } 28 | 29 | /* week and day number styling */ 30 | .fc-day-top.fc-other-month { 31 | opacity: 0.3; } 32 | 33 | .fc-dayGrid-view .fc-week-number, 34 | .fc-dayGrid-view .fc-day-number { 35 | padding: 2px; } 36 | 37 | .fc-dayGrid-view th.fc-week-number, 38 | .fc-dayGrid-view th.fc-day-number { 39 | padding: 0 2px; 40 | /* column headers can't have as much v space */ } 41 | 42 | .fc-ltr .fc-dayGrid-view .fc-day-top .fc-day-number { 43 | float: right; } 44 | 45 | .fc-rtl .fc-dayGrid-view .fc-day-top .fc-day-number { 46 | float: left; } 47 | 48 | .fc-ltr .fc-dayGrid-view .fc-day-top .fc-week-number { 49 | float: left; 50 | border-radius: 0 0 3px 0; } 51 | 52 | .fc-rtl .fc-dayGrid-view .fc-day-top .fc-week-number { 53 | float: right; 54 | border-radius: 0 0 0 3px; } 55 | 56 | .fc-dayGrid-view .fc-day-top .fc-week-number { 57 | min-width: 1.5em; 58 | text-align: center; 59 | background-color: #f2f2f2; 60 | color: #808080; } 61 | 62 | /* when week/day number have own column */ 63 | .fc-dayGrid-view td.fc-week-number { 64 | text-align: center; } 65 | 66 | .fc-dayGrid-view td.fc-week-number > * { 67 | /* work around the way we do column resizing and ensure a minimum width */ 68 | display: inline-block; 69 | min-width: 1.25em; } 70 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/daygrid/main.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | FullCalendar Day Grid Plugin v4.2.0 3 | Docs & License: https://fullcalendar.io/ 4 | (c) 2019 Adam Shaw 5 | */.fc-dayGridDay-view .fc-content-skeleton,.fc-dayGridWeek-view .fc-content-skeleton{padding-bottom:1em}.fc-dayGrid-view .fc-body .fc-row{min-height:4em}.fc-row.fc-rigid{overflow:hidden}.fc-row.fc-rigid .fc-content-skeleton{position:absolute;top:0;left:0;right:0}.fc-day-top.fc-other-month{opacity:.3}.fc-dayGrid-view .fc-day-number,.fc-dayGrid-view .fc-week-number{padding:2px}.fc-dayGrid-view th.fc-day-number,.fc-dayGrid-view th.fc-week-number{padding:0 2px}.fc-ltr .fc-dayGrid-view .fc-day-top .fc-day-number{float:right}.fc-rtl .fc-dayGrid-view .fc-day-top .fc-day-number{float:left}.fc-ltr .fc-dayGrid-view .fc-day-top .fc-week-number{float:left;border-radius:0 0 3px}.fc-rtl .fc-dayGrid-view .fc-day-top .fc-week-number{float:right;border-radius:0 0 0 3px}.fc-dayGrid-view .fc-day-top .fc-week-number{min-width:1.5em;text-align:center;background-color:#f2f2f2;color:grey}.fc-dayGrid-view td.fc-week-number{text-align:center}.fc-dayGrid-view td.fc-week-number>*{display:inline-block;min-width:1.25em} -------------------------------------------------------------------------------- /src/3pt/fullcalendar/list/main.css: -------------------------------------------------------------------------------- 1 | /*! 2 | FullCalendar List View Plugin v4.2.0 3 | Docs & License: https://fullcalendar.io/ 4 | (c) 2019 Adam Shaw 5 | */ 6 | /* List View 7 | --------------------------------------------------------------------------------------------------*/ 8 | /* possibly reusable */ 9 | .fc-event-dot { 10 | display: inline-block; 11 | width: 10px; 12 | height: 10px; 13 | border-radius: 5px; } 14 | 15 | /* view wrapper */ 16 | .fc-rtl .fc-list-view { 17 | direction: rtl; 18 | /* unlike core views, leverage browser RTL */ } 19 | 20 | .fc-list-view { 21 | border-width: 1px; 22 | border-style: solid; } 23 | 24 | /* table resets */ 25 | .fc .fc-list-table { 26 | table-layout: auto; 27 | /* for shrinkwrapping cell content */ } 28 | 29 | .fc-list-table td { 30 | border-width: 1px 0 0; 31 | padding: 8px 14px; } 32 | 33 | .fc-list-table tr:first-child td { 34 | border-top-width: 0; } 35 | 36 | /* day headings with the list */ 37 | .fc-list-heading { 38 | border-bottom-width: 1px; } 39 | 40 | .fc-list-heading td { 41 | font-weight: bold; } 42 | 43 | .fc-ltr .fc-list-heading-main { 44 | float: left; } 45 | 46 | .fc-ltr .fc-list-heading-alt { 47 | float: right; } 48 | 49 | .fc-rtl .fc-list-heading-main { 50 | float: right; } 51 | 52 | .fc-rtl .fc-list-heading-alt { 53 | float: left; } 54 | 55 | /* event list items */ 56 | .fc-list-item.fc-has-url { 57 | cursor: pointer; 58 | /* whole row will be clickable */ } 59 | 60 | .fc-list-item-marker, 61 | .fc-list-item-time { 62 | white-space: nowrap; 63 | width: 1px; } 64 | 65 | /* make the dot closer to the event title */ 66 | .fc-ltr .fc-list-item-marker { 67 | padding-right: 0; } 68 | 69 | .fc-rtl .fc-list-item-marker { 70 | padding-left: 0; } 71 | 72 | .fc-list-item-title a { 73 | /* every event title cell has an tag */ 74 | text-decoration: none; 75 | color: inherit; } 76 | 77 | .fc-list-item-title a[href]:hover { 78 | /* hover effect only on titles with hrefs */ 79 | text-decoration: underline; } 80 | 81 | /* message when no events */ 82 | .fc-list-empty-wrap2 { 83 | position: absolute; 84 | top: 0; 85 | left: 0; 86 | right: 0; 87 | bottom: 0; } 88 | 89 | .fc-list-empty-wrap1 { 90 | width: 100%; 91 | height: 100%; 92 | display: table; } 93 | 94 | .fc-list-empty { 95 | display: table-cell; 96 | vertical-align: middle; 97 | text-align: center; } 98 | 99 | .fc-unthemed .fc-list-empty { 100 | /* theme will provide own background */ 101 | background-color: #eee; } 102 | -------------------------------------------------------------------------------- /src/3pt/fullcalendar/list/main.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | FullCalendar List View Plugin v4.2.0 3 | Docs & License: https://fullcalendar.io/ 4 | (c) 2019 Adam Shaw 5 | */.fc-event-dot{display:inline-block;width:10px;height:10px;border-radius:5px}.fc-rtl .fc-list-view{direction:rtl}.fc-list-view{border-width:1px;border-style:solid}.fc .fc-list-table{table-layout:auto}.fc-list-table td{border-width:1px 0 0;padding:8px 14px}.fc-list-table tr:first-child td{border-top-width:0}.fc-list-heading{border-bottom-width:1px}.fc-list-heading td{font-weight:700}.fc-ltr .fc-list-heading-main{float:left}.fc-ltr .fc-list-heading-alt,.fc-rtl .fc-list-heading-main{float:right}.fc-rtl .fc-list-heading-alt{float:left}.fc-list-item.fc-has-url{cursor:pointer}.fc-list-item-marker,.fc-list-item-time{white-space:nowrap;width:1px}.fc-ltr .fc-list-item-marker{padding-right:0}.fc-rtl .fc-list-item-marker{padding-left:0}.fc-list-item-title a{text-decoration:none;color:inherit}.fc-list-item-title a[href]:hover{text-decoration:underline}.fc-list-empty-wrap2{position:absolute;top:0;left:0;right:0;bottom:0}.fc-list-empty-wrap1{width:100%;height:100%;display:table}.fc-list-empty{display:table-cell;vertical-align:middle;text-align:center}.fc-unthemed .fc-list-empty{background-color:#eee} -------------------------------------------------------------------------------- /src/3pt/fullcalendar/timegrid/main.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | FullCalendar Time Grid Plugin v4.2.0 3 | Docs & License: https://fullcalendar.io/ 4 | (c) 2019 Adam Shaw 5 | */.fc-timeGrid-view .fc-day-grid{position:relative;z-index:2}.fc-timeGrid-view .fc-day-grid .fc-row{min-height:3em}.fc-timeGrid-view .fc-day-grid .fc-row .fc-content-skeleton{padding-bottom:1em}.fc .fc-axis{vertical-align:middle;padding:0 4px;white-space:nowrap}.fc-ltr .fc-axis{text-align:right}.fc-rtl .fc-axis{text-align:left}.fc-time-grid,.fc-time-grid-container{position:relative;z-index:1}.fc-time-grid{min-height:100%}.fc-time-grid table{border:0 hidden transparent}.fc-time-grid>.fc-bg{z-index:1}.fc-time-grid .fc-slats,.fc-time-grid>hr{position:relative;z-index:2}.fc-time-grid .fc-content-col{position:relative}.fc-time-grid .fc-content-skeleton{position:absolute;z-index:3;top:0;left:0;right:0}.fc-time-grid .fc-business-container{position:relative;z-index:1}.fc-time-grid .fc-bgevent-container{position:relative;z-index:2}.fc-time-grid .fc-highlight-container{z-index:3;position:relative}.fc-time-grid .fc-event-container{position:relative;z-index:4}.fc-time-grid .fc-now-indicator-line{z-index:5}.fc-time-grid .fc-mirror-container{position:relative;z-index:6}.fc-time-grid .fc-slats td{height:1.5em;border-bottom:0}.fc-time-grid .fc-slats .fc-minor td{border-top-style:dotted}.fc-time-grid .fc-highlight{position:absolute;left:0;right:0}.fc-ltr .fc-time-grid .fc-event-container{margin:0 2.5% 0 2px}.fc-rtl .fc-time-grid .fc-event-container{margin:0 2px 0 2.5%}.fc-time-grid .fc-bgevent,.fc-time-grid .fc-event{position:absolute;z-index:1}.fc-time-grid .fc-bgevent{left:0;right:0}.fc-time-grid-event{margin-bottom:1px}.fc-time-grid-event-inset{-webkit-box-shadow:0 0 0 1px #fff;box-shadow:0 0 0 1px #fff}.fc-time-grid-event.fc-not-start{border-top-width:0;padding-top:1px;border-top-left-radius:0;border-top-right-radius:0}.fc-time-grid-event.fc-not-end{border-bottom-width:0;padding-bottom:1px;border-bottom-left-radius:0;border-bottom-right-radius:0}.fc-time-grid-event .fc-content{overflow:hidden;max-height:100%}.fc-time-grid-event .fc-time,.fc-time-grid-event .fc-title{padding:0 1px}.fc-time-grid-event .fc-time{font-size:.85em;white-space:nowrap}.fc-time-grid-event.fc-short .fc-content{white-space:nowrap}.fc-time-grid-event.fc-short .fc-time,.fc-time-grid-event.fc-short .fc-title{display:inline-block;vertical-align:top}.fc-time-grid-event.fc-short .fc-time span{display:none}.fc-time-grid-event.fc-short .fc-time:before{content:attr(data-start)}.fc-time-grid-event.fc-short .fc-time:after{content:"\000A0-\000A0"}.fc-time-grid-event.fc-short .fc-title{font-size:.85em;padding:0}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer{left:0;right:0;bottom:0;height:8px;overflow:hidden;line-height:8px;font-size:11px;font-family:monospace;text-align:center;cursor:s-resize}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after{content:"="}.fc-time-grid-event.fc-selected .fc-resizer{border-radius:5px;border-width:1px;width:8px;height:8px;border-style:solid;border-color:inherit;background:#fff;left:50%;margin-left:-5px;bottom:-5px}.fc-time-grid .fc-now-indicator-line{border-top-width:1px;left:0;right:0}.fc-time-grid .fc-now-indicator-arrow{margin-top:-5px}.fc-ltr .fc-time-grid .fc-now-indicator-arrow{left:0;border-width:5px 0 5px 6px;border-top-color:transparent;border-bottom-color:transparent}.fc-rtl .fc-time-grid .fc-now-indicator-arrow{right:0;border-width:5px 6px 5px 0;border-top-color:transparent;border-bottom-color:transparent} -------------------------------------------------------------------------------- /src/3pt/svg.foreignobject.js: -------------------------------------------------------------------------------- 1 | 2 | SVG.ForeignObject = SVG.invent({ 3 | // Initialize node 4 | create: 'foreignObject' 5 | 6 | // Inherit from 7 | , inherit: SVG.Shape 8 | 9 | // Add parent method 10 | , construct: { 11 | // Create a rect element 12 | foreignObject: function(width, height) { 13 | return this.put(new SVG.ForeignObject()).size(width, height) 14 | } 15 | } 16 | , extend: { 17 | appendChild: function (child, attrs) { 18 | var newChild = typeof(child)=='string' ? document.createElement(child) : child 19 | if (typeof(attrs)=='object'){ 20 | for(a in attrs) newChild[a] = attrs[a] 21 | } 22 | this.node.appendChild(newChild) 23 | return this 24 | }, 25 | getChild: function (index) { 26 | return this.node.childNodes[index] 27 | } 28 | } 29 | }); -------------------------------------------------------------------------------- /src/3pt/x-frame-bypass.js: -------------------------------------------------------------------------------- 1 | customElements.define('x-frame-bypass', class extends HTMLIFrameElement { 2 | constructor () { 3 | super() 4 | } 5 | connectedCallback () { 6 | this.load(this.src) 7 | this.src = '' 8 | this.sandbox = '' + this.sandbox || 'allow-forms allow-modals allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts allow-top-navigation-by-user-activation' // all except allow-top-navigation 9 | } 10 | load (url, options) { 11 | if (!url || !url.startsWith('http')) 12 | throw new Error(`X-Frame-Bypass src ${url} does not start with http(s)://`) 13 | console.log('X-Frame-Bypass loading:', url) 14 | this.srcdoc = ` 15 | 16 | 37 | 38 | 39 |
40 | 41 | ` 42 | this.fetchProxy(url, options, 0).then(res => res.text()).then(data => { 43 | if (data) 44 | this.srcdoc = data.replace(/]*)>/i, ` 45 | 46 | `) 64 | }).catch(e => console.error('Cannot load X-Frame-Bypass:', e)) 65 | } 66 | fetchProxy (url, options, i) { 67 | const proxy = [ 68 | 'https://cors.io/?', 69 | 'https://jsonp.afeld.me/?url=', 70 | 'https://cors-anywhere.herokuapp.com/' 71 | ] 72 | return fetch(proxy[i] + url, options).then(res => { 73 | if (!res.ok) 74 | throw new Error(`${res.status} ${res.statusText}`); 75 | return res 76 | }).catch(error => { 77 | if (i === proxy.length - 1) 78 | throw error 79 | return this.fetchProxy(url, options, i + 1) 80 | }) 81 | } 82 | }, {extends: 'iframe'}) -------------------------------------------------------------------------------- /src/core_modules/core/core.clip.js: -------------------------------------------------------------------------------- 1 | function addpolymorph_coreClipboard(polymorph_core) { 2 | // Clipboard is a rotary buffer 3 | polymorph_core.clipboard = []; 4 | polymorph_core.toClip = function(itm) { 5 | polymorph_core.clipboard.unshift(itm); 6 | if (polymorph_core.clipboard.length > 10) { 7 | polymorph_core.clipboard.pop(); 8 | } 9 | } 10 | } 11 | 12 | addpolymorph_coreClipboard(polymorph_core); 13 | 14 | /* 15 | mouseleave 16 | -> polymorph_core.toclip (an id){ 17 | 18 | } 19 | 20 | mouseenter: 21 | call before: -> polymorph_core.fromclip(an id){ 22 | 23 | } 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | */ -------------------------------------------------------------------------------- /src/core_modules/core/core.debug.js: -------------------------------------------------------------------------------- 1 | polymorph_core.generateOperatorTree=()=>{ 2 | for (let i in polymorph_core.items){ 3 | if (polymorph_core.items[i]._od){ 4 | if (!polymorph_core.containers[i]){ 5 | console.log(`ERR uncontained container ${i}`); 6 | } 7 | } 8 | if (polymorph_core.items[i]._rd){ 9 | if (!polymorph_core.containers[i]){ 10 | console.log(`ERR unrected rect ${i}`); 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/core_modules/core/core.dedup.js: -------------------------------------------------------------------------------- 1 | { 2 | // Dedup detection 3 | const broadcast = new BroadcastChannel('channel1'); 4 | let instance_uuid = polymorph_core.guid(); 5 | let checkerPromiseResolve = undefined; 6 | broadcast.onmessage = (event) => { 7 | if (event.data.url.replace("#", "") == window.location.href.replace("#", "") && event.data.uuid != instance_uuid) { 8 | if (checkerPromiseResolve) { 9 | checkerPromiseResolve(true); 10 | checkerPromiseResolve = undefined; 11 | } else if (!event.data.echo) { 12 | broadcast.postMessage({ 13 | url: window.location.href, 14 | uuid: instance_uuid, 15 | echo: true 16 | }); 17 | } 18 | } 19 | }; 20 | let checkForURLConflict = async() => { 21 | return new Promise((res) => { 22 | checkerPromiseResolve = res; 23 | broadcast.postMessage({ 24 | url: window.location.href, 25 | uuid: instance_uuid 26 | }) 27 | setTimeout(() => { 28 | if (checkerPromiseResolve) { 29 | checkerPromiseResolve(false); 30 | checkerPromiseResolve = undefined; 31 | } 32 | }, 500); 33 | }); 34 | } 35 | 36 | polymorph_core.blockIfURLConflict = async() => { 37 | let hasUrlConflict = await checkForURLConflict(); 38 | if (hasUrlConflict) { 39 | alt_alive_warning.style.visibility = "visible"; 40 | return; 41 | } 42 | } 43 | 44 | let alt_alive_warning = document.createElement("div"); 45 | alt_alive_warning.innerHTML = ` 46 |
47 |

Warning! This document is already open in another window. Please use the other window instead.

48 |
49 | `; 50 | alt_alive_warning.style.cssText = ` 51 | display:flex; 52 | visibility:hidden; 53 | place-items: center center; 54 | position:absolute; 55 | height:100%; 56 | width:100%; 57 | z-index:5; 58 | background: rgba(0,0,0,0.8); 59 | color:white; 60 | text-align:center; 61 | `; 62 | document.body.appendChild(alt_alive_warning); 63 | 64 | } -------------------------------------------------------------------------------- /src/core_modules/core/core.itemfx.js: -------------------------------------------------------------------------------- 1 | //Do we even need these? Probably not.... 2 | polymorph_core.isLinked = function (A, B) { 3 | let ret = 0; //unlinked 4 | if (polymorph_core.items[A].to && polymorph_core.items[A].to[B]) { 5 | ret = ret + 1;// 1: there is a link FROM A to B 6 | } 7 | if (polymorph_core.items[B].to && polymorph_core.items[B].to[A]) { 8 | ret = ret + 2;// 2: there is a link FROM B to A 9 | } 10 | return ret; 11 | } 12 | 13 | polymorph_core.link = function (A, B, settings = {}) { 14 | if (settings == true) { 15 | settings = { undirected: true }; 16 | } 17 | let toProp = settings.toProp || "to"; 18 | let fromProp = settings.fromProp; 19 | let undirected = settings.undirected; 20 | polymorph_core.items[A][toProp] = polymorph_core.items[A][toProp] || {}; 21 | polymorph_core.items[A][toProp][B] = polymorph_core.items[A][toProp][B] || true; 22 | if (fromProp) { 23 | polymorph_core.items[B][fromProp] = polymorph_core.items[B][fromProp] || {}; 24 | polymorph_core.items[B][fromProp][A] = polymorph_core.items[B][fromProp][A] || true; 25 | } 26 | if (undirected) { 27 | polymorph_core.link(B, A, settings); 28 | } 29 | } 30 | polymorph_core.unlink = function (A, B, settings = {}) { 31 | if (settings == true) { 32 | settings = { undirected: true }; 33 | } 34 | let toProp = settings.toProp || "to"; 35 | let fromProp = settings.fromProp; 36 | let undirected = settings.undirected; 37 | polymorph_core.items[A][toProp] = polymorph_core.items[A][toProp] || {}; 38 | delete polymorph_core.items[A][toProp][B]; 39 | if (fromProp) { 40 | polymorph_core.items[B][fromProp] = polymorph_core.items[B][fromProp] || {}; 41 | delete polymorph_core.items[B][fromProp][A]; 42 | } 43 | if (undirected) { 44 | polymorph_core.unlink(B, A); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/core_modules/core/core.operator.js: -------------------------------------------------------------------------------- 1 | polymorph_core.operatorTemplate = function(container, defaultSettings) { 2 | this.container = container; 3 | Object.defineProperty(this, "settings", { 4 | get: () => { 5 | return container.settings.data; 6 | } 7 | }); 8 | //facilitate creation of this.settings if it doesnt exist. 9 | Object.assign(defaultSettings, this.settings); 10 | this.settings = {}; 11 | Object.assign(this.settings, defaultSettings); 12 | this.rootdiv = document.createElement("div"); 13 | this.rootStyle = document.createElement("style"); 14 | container.div.appendChild(this.rootStyle); 15 | setTimeout(() => polymorph_core.updateCSS()); 16 | this.rootdiv.style.height = "100%"; 17 | this.rootdiv.style.overflow = "auto"; 18 | container.div.appendChild(this.rootdiv); 19 | this.createItem = (id) => { 20 | let itm = {}; 21 | if (!id) { 22 | id = polymorph_core.insertItem(itm); 23 | } 24 | if (this.settings.filter) { 25 | polymorph_core.items[id][this.settings.filter] = true; 26 | } 27 | return id; 28 | } 29 | 30 | this.deleteItem = (id) => { 31 | delete polymorph_core.items[id][this.settings.filter]; 32 | //container.fire("updateItem", { id: id }); 33 | //container.fire("focusItem", { id: undefined }); 34 | } 35 | 36 | this.itemRelevant = (id) => { 37 | if (this.settings.filter == "") { 38 | return true; //if filter doesnt exist it should be undefined 39 | } else { 40 | if (polymorph_core.items[id][this.settings.filter] != undefined) { 41 | return true; 42 | } else { 43 | return false; 44 | } 45 | } 46 | } 47 | 48 | this.intervalsToClear = []; 49 | this.remove = () => { 50 | if (this.intervalsToClear) this.intervalsToClear.forEach(i => clearInterval(i)); 51 | } 52 | }; 53 | 54 | // make sure that new operators are properly instantiated 55 | (() => { 56 | let callInProgress = false; 57 | polymorph_core.on("updateItem", (d) => { 58 | if (callInProgress) return; 59 | callInProgress = true; 60 | let itm = polymorph_core.items[d.id]; 61 | if (itm._od && !polymorph_core.containers[d.id]) { 62 | polymorph_core.containers[d.id] = new polymorph_core.container(d.id); 63 | polymorph_core.containers[d.id].refresh(); 64 | } 65 | if (itm._od && polymorph_core.containers[d.id].operator && polymorph_core.containers[d.id].operator.constructor != polymorph_core.operators[polymorph_core.containers[d.id].settings.t].constructor) { 66 | //cleanup and reinstantiate 67 | let container = polymorph_core.containers[d.id]; 68 | while (container.div.children.length) container.div.children[0].remove(); 69 | container.operator = new polymorph_core.operators[polymorph_core.containers[d.id].settings.t].constructor(container); 70 | 71 | polymorph_core.rects[container.settings.p].tieContainer(container.id); 72 | polymorph_core.rects[container.settings.p].refresh(); // kick it so the container actually loads its operator 73 | } 74 | callInProgress = false; 75 | }) 76 | })(); -------------------------------------------------------------------------------- /src/core_modules/core/core.static.js: -------------------------------------------------------------------------------- 1 | // core.static allows the polymorph to boot up loading a static file if configured to do so. 2 | _polymorph_core.prototype.isStaticMode = () => { 3 | return !(window.polymorph_file_list); 4 | } 5 | 6 | _polymorph_core.prototype.handleStaticData = () => { 7 | // check for static item 8 | if (window.polymorph_static_data) { 9 | let data = window.polymorph_static_data; 10 | // prevent alert errors downstream in integrateData 11 | polymorph_core.currentDocID = data._meta.id; 12 | polymorph_core.integrateData(data, ""); 13 | } 14 | } 15 | 16 | if (polymorph_core.isStaticMode()) { 17 | // We aren't being piloted by a fileManager 18 | // patch some save functions that shouldn't run 19 | polymorph_core.addCreationOption = () => {}; // do nothing 20 | 21 | // start the polymorph_core ourselves, in static mode (any editable deployment of polymorph_core should have a filemanager); 22 | polymorph_core.start(true); 23 | 24 | //unshow the wall 25 | document.querySelector(".wall").style.display = "none"; 26 | // light shade of purple for the body since purplestars are gone 27 | document.querySelector(".rectspace").style.background = "purple"; 28 | 29 | } -------------------------------------------------------------------------------- /src/core_modules/core/core.workersync.js: -------------------------------------------------------------------------------- 1 | 2 | const broadcast = new BroadcastChannel('channel1'); 3 | broadcast.onmessage = (event) => { 4 | if (event.data =="hello world") { 5 | broadcast.postMessage("hiii"); 6 | } 7 | }; -------------------------------------------------------------------------------- /src/core_modules/ui/core.dragdrop.js: -------------------------------------------------------------------------------- 1 | polymorph_core.initiateDragDrop = function (itemID, _settings) { 2 | if (polymorph_core._dragdropdata.tempItemDiv) return; 3 | let settings = { 4 | x: polymorph_core._dragdropdata.mouseX, 5 | y: polymorph_core._dragdropdata.mouseY, 6 | property: "title", 7 | displayText: undefined, //define to overwrite the property 8 | sender: undefined 9 | }; 10 | Object.assign(settings, _settings); 11 | let tempItemDiv = htmlwrap(`
`); 12 | tempItemDiv.innerText = polymorph_core.items[itemID][settings.property]; 13 | document.body.appendChild(tempItemDiv); 14 | polymorph_core._dragdropdata.tempItemDiv = tempItemDiv; 15 | settings.itemID = itemID; 16 | polymorph_core._dragdropdata.settings = settings; 17 | //when mouseup, fire a createItem on the new operator. If not ctrl, fire a deleteItem on the old operator. 18 | } 19 | 20 | polymorph_core._dragdropdata = {}; 21 | 22 | document.addEventListener("mousemove", (e) => { 23 | polymorph_core._dragdropdata.mouseX = e.clientX; 24 | polymorph_core._dragdropdata.mouseY = e.clientY; 25 | if (polymorph_core._dragdropdata.tempItemDiv) { 26 | polymorph_core._dragdropdata.tempItemDiv.style.top = e.clientY; 27 | polymorph_core._dragdropdata.tempItemDiv.style.left = e.clientX; 28 | } 29 | }) 30 | 31 | document.addEventListener("mouseup", (e) => { 32 | if (polymorph_core._dragdropdata.tempItemDiv) { 33 | polymorph_core._dragdropdata.tempItemDiv.remove(); 34 | let elementUnderMouse = document.elementFromPoint(e.clientX, e.clientY); 35 | while (elementUnderMouse.shadowRoot) { 36 | elementUnderMouse = elementUnderMouse.shadowRoot.elementFromPoint(e.clientX, e.clientY); 37 | } 38 | console.log(elementUnderMouse); 39 | //Figure out which container this belongs to... 40 | //todo: make this work for non shadow roots. 41 | let rootNode = elementUnderMouse.getRootNode(); 42 | let container_id = rootNode.host.parentElement.parentElement.dataset.containerid; //actually the rect's container for it. This will need to change if we remove rects. 43 | console.log(container_id); 44 | let settings = polymorph_core._dragdropdata.settings; 45 | if (container_id != settings.sender) { 46 | polymorph_core.containers[container_id]._fire("createItem", { id: settings.itemID, sender: "dragdrop" }); 47 | let targetContainerOptions = polymorph_core.operators[polymorph_core.containers[container_id].settings.t].options 48 | if (!targetContainerOptions.single_store) polymorph_core.containers[settings.sender]._fire("deleteItem", { id: settings.itemID, sender: "dragdrop" }); 49 | delete polymorph_core._dragdropdata.tempItemDiv; 50 | } 51 | } 52 | }) 53 | 54 | //edge case: drop onto not a container -------------------------------------------------------------------------------- /src/core_modules/ui/richText.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | // rich text 3 | polymorph_core.RTRenderProperty = (prop) => { 4 | // convert markdown into HTML 5 | return prop; 6 | } 7 | 8 | 9 | polymorph_core.RTParseElement = (el, id, prop) => { 10 | // check if there are any child images 11 | let deepCloned = el.cloneNode(true); 12 | let strayImages = 0; 13 | if (deepCloned.children) { 14 | for (c of deepCloned.children) { 15 | if (c.tagName == "IMG" && c.src.slice(0, 5) == "data:") { 16 | strayImages++; 17 | let rq = new XMLHttpRequest(); 18 | rq.onreadystatechange = (e) => { 19 | if (rq.readyState == XMLHttpRequest.DONE) { 20 | if (rq.status == 200) { 21 | c.src = `${window.location.protocol}//${window.location.host}/getImage/${rq.responseText}.png`; 22 | } 23 | strayImages--; 24 | if (strayImages == 0) { 25 | // send an updateItem 26 | polymorph_core.items[id][prop] = deepCloned.innerHTML; 27 | polymorph_core.fire("updateItem", { id: id, sender: polymorph_core }); 28 | } 29 | } 30 | } 31 | rq.open("POST", `${window.location.protocol}//${window.location.host}/saveImage`); 32 | rq.setRequestHeader('Content-Type', c.src.split(/;/g)[0].slice(5)); 33 | rq.send(c.src); 34 | } 35 | } 36 | } 37 | // if there are, grab the url as a dataurl 38 | // POST the dataurl to a backend image handler 39 | // for now, just check whether localhost will take it 40 | // when it comes back, fire an updateItem to update it. 41 | return el.innerHTML; 42 | } 43 | })(); -------------------------------------------------------------------------------- /src/core_modules/unmaintained/core.palette.js: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////////////// 2 | //palette functions 3 | 4 | /* 5 | Palette looks like this: 6 | { 7 | rectOuterDivColour: "rgba(stuff)", 8 | rectInnerDivColour: optional - defaults to rectOuterDivColour 9 | rectTabColour: optional - defaults to rectOuterDivColour 10 | containerInnerColour 11 | } 12 | 13 | 14 | 15 | */ 16 | 17 | polymorph_core.rect.prototype.changePalette = function (palette) { 18 | this.outerDiv.style.background = palette.rectOuterDivColour; 19 | this.innerDivs.forEach((v) => { 20 | v.style.background = palette.rectInnerDivColour || palette.rectOuterDivColour; 21 | }) 22 | this.tabspans.forEach((v) => { 23 | v.style.background = palette.rectTabColour || palette.rectOuterDivColour; 24 | }) 25 | this.passthrough("changePalette",palette); 26 | } 27 | 28 | polymorph_core.changePalette = function (palette) { 29 | for (let i in polymorph_core.baseRects) { 30 | polymorph_core.baseRects[i].changePalette(palette); 31 | } 32 | } 33 | 34 | polymorph_core.container.prototype.changePalette = function (palette) { 35 | this.topdiv.style.background = palette.containerInnerColour; 36 | } 37 | 38 | polymorph_core.on("UIstart", () => { 39 | let paletteDialog = document.createElement('div'); 40 | paletteDialog.classList.add("dialog"); 41 | paletteDialog = dialogManager.checkDialogs(paletteDialog)[0]; 42 | innerDialog = paletteDialog.querySelector(".innerDialog"); 43 | document.body.appendChild(paletteDialog); // where root is the document 44 | let d = document.createElement("div"); 45 | d.innerHTML = ` 46 |

Palette management

47 | 49 |
50 | 51 |
52 | 57 | 22 | `; 23 | 24 | container.on("updateItem", (d) => { 25 | //add a change 26 | let id = d.id; 27 | if (d.loadProcess) return; 28 | if (this.rootdiv.querySelector(".nochanges")) this.rootdiv.querySelector(".nochanges").remove(); 29 | if (!this.rootdiv.querySelector(`[data-id="${id}"]`)) { 30 | this.rootdiv.querySelector(".changelog").appendChild(htmlwrap(` 31 |

"${id}":${JSON.stringify(polymorph_core.items[id])}

`)) 32 | } else { 33 | this.rootdiv.querySelector(`[data-id="${id}"]`).innerText = `"${id}":${JSON.stringify(polymorph_core.items[id])}`; 34 | } 35 | }) 36 | 37 | container.on("deleteItem", (d) => { 38 | let id = d.id; 39 | //something was deleted. we are logging this deletion with just the word "DELETE" 40 | if (this.rootdiv.querySelector(".nochanges")) this.rootdiv.querySelector(".nochanges").remove(); 41 | if (!this.rootdiv.querySelector(`[data-id="${id}"]`)) { 42 | this.rootdiv.querySelector(".changelog").appendChild(htmlwrap(` 43 |

"${id}":{}

`)) 44 | } else { 45 | this.rootdiv.querySelector(`[data-id="${id}"]`).innerText = `"${id}":{}`; 46 | } 47 | }) 48 | this.rootdiv.querySelector("button").addEventListener("click", (e) => { 49 | eval(this.settings.submissionTransmitter)(`{${Array.from(this.rootdiv.querySelector(".changelog").children).map(i => i.innerText).join(",")}}`); 50 | }) 51 | 52 | //Handle the settings dialog click! 53 | this.dialogDiv = document.createElement("div"); 54 | this.dialogDiv.innerHTML = ``; 55 | let options = { 56 | submissionTransmitter: new polymorph_core._option({ 57 | div: this.dialogDiv, 58 | type: "textarea", 59 | object: this.settings, 60 | property: "submissionTransmitter", 61 | label: "Submission function" 62 | }) 63 | } 64 | this.showDialog = function () { 65 | // update your dialog elements with your settings 66 | for (let i in options) options[i].load(); 67 | } 68 | this.dialogUpdateSettings = function () { 69 | // This is called when your dialog is closed. Use it to update your container! 70 | } 71 | 72 | }); -------------------------------------------------------------------------------- /src/operators/itemcluster/contextmenu/orbit.js: -------------------------------------------------------------------------------- 1 | function _itemcluster_extend_contextmenu_orbit() { 2 | let orbitBtn = htmlwrap(`
  • Toggle orbit around point
  • `); 3 | this.rootContextMenu.appendChild(orbitBtn); 4 | let orbiterParams; 5 | orbitBtn.addEventListener("click", (e) => { 6 | if (orbiterParams) { 7 | // stop orbiting 8 | clearInterval(orbiterParams.interval); 9 | orbiterParams = undefined; 10 | } else { 11 | orbiterParams = {}; 12 | 13 | // Find the centre to orbit around 14 | let coords = this.mapPageToSvgCoords(e.pageX, e.pageY); 15 | orbiterParams.cx = coords.x; 16 | orbiterParams.cy = coords.y; 17 | orbiterParams.orbitalSpeed = 0.01; // rads / tick 18 | orbiterParams.orbitalSpeedDropoff = 0.999; // percent 19 | // start orbiting 20 | orbiterParams.interval = setInterval(() => { 21 | if (this.container.visible()) { 22 | let visibleItems = this.getVisibleItems(); 23 | visibleItems.map(i => { 24 | i.r = Math.sqrt((i.x - orbiterParams.cx) * (i.x - orbiterParams.cx) + (i.y - orbiterParams.cy) * (i.y - orbiterParams.cy)); 25 | i.t = Math.atan2((i.y - orbiterParams.cy), (i.x - orbiterParams.cx)); 26 | let newAngle = i.t + orbiterParams.orbitalSpeed * (orbiterParams.orbitalSpeedDropoff ** i.r); 27 | i.nx = orbiterParams.cx + i.r * Math.cos(newAngle); 28 | i.ny = orbiterParams.cy + i.r * Math.sin(newAngle); 29 | polymorph_core.items[i.id].itemcluster.viewData[this.settings.currentViewName].x = i.nx; 30 | polymorph_core.items[i.id].itemcluster.viewData[this.settings.currentViewName].y = i.ny; 31 | this.container.fire("updateItem", { id: i.id, sender: this }); 32 | this.arrangeItem(i.id); 33 | }) 34 | } 35 | }, 500); 36 | } 37 | this.rootContextMenu.style.display = "none"; 38 | }); 39 | 40 | 41 | } -------------------------------------------------------------------------------- /src/operators/phone/subframe.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerOperator("subframe", { targetForward: true, hidden: true }, function (container) { 2 | polymorph_core.operatorTemplate.call(this, container, {}); 3 | this.rdv = document.createElement("div"); 4 | this.rdv.style.marginLeft = "10px"; 5 | this.container.rect.listContainer.querySelector(`[data-containerid="${this.container.id}"]`).appendChild(this.rdv); 6 | //////////////////Handle polymorph_core item updates////////////////// 7 | 8 | this.refresh = function () { 9 | polymorph_core.rects[this.rectID].refresh(); 10 | } 11 | 12 | //////////////////Handling local changes to push to polymorph_core////////////////// 13 | Object.defineProperty(this, "rect", { 14 | get: () => { 15 | return polymorph_core.rects[this.rectID]; 16 | } 17 | }) 18 | 19 | this.tieRect = function (rectID) { 20 | this.rectID = rectID; 21 | this.rdv.appendChild(polymorph_core.rects[rectID].listContainer); 22 | polymorph_core.rects[rectID].refresh(); 23 | } 24 | 25 | //Check if i have any rects waiting for pickup 26 | if (polymorph_core.rectLoadCallbacks[container.id]) { 27 | this.tieRect(polymorph_core.rectLoadCallbacks[container.id][0]); 28 | delete polymorph_core.rectLoadCallbacks[container.id]; 29 | } else if (!this.settings.operatorClonedFrom) { 30 | let rectID = polymorph_core.newRect(container.id); 31 | this.tieRect(rectID); 32 | } 33 | //////////////////Handle polymorph_core item updates////////////////// 34 | 35 | this.refresh = function () { 36 | this.rect.refresh(); 37 | } 38 | //For interoperability between views you may fire() and on() your own events. You may only pass one object to the fire() function; use the properties of that object for additional detail. 39 | this.processSettings = function () { 40 | } 41 | 42 | //////////////////Handling local changes to push to polymorph_core////////////////// 43 | 44 | //Saving and loading 45 | this.toSaveData = function () { 46 | this.settings.rectUnderData = this.rect.toSaveData(); 47 | return this.settings; 48 | } 49 | 50 | //Handle the settings dialog click! 51 | this.dialogDiv = document.createElement("div"); 52 | this.dialogDiv.innerHTML = `Nothing to show yet :3`; 53 | this.showDialog = function () { 54 | // update your dialog elements with your settings 55 | } 56 | this.dialogUpdateSettings = function () { 57 | // pull settings and update when your dialog is closed. 58 | } 59 | 60 | this.getOperator = function (id) { 61 | return this.rect.getOperator(id); 62 | } 63 | this.getOperatorPath = function (id) { 64 | return this.rect.getOperatorPath(id); 65 | } 66 | this.listOperators = function (list) { 67 | this.rect.listOperators(list); 68 | } 69 | }); -------------------------------------------------------------------------------- /src/operators/ruigen/annipairs.js: -------------------------------------------------------------------------------- 1 | 2 | ///////annihilation-pairs///// 3 | rui_op['annipairs'] = (function () { 4 | var annipair = []; 5 | var annipairSettings = { 6 | r: 2, 7 | bitprob: 0.5 8 | } 9 | 10 | setInterval(() => { 11 | //remove archaics 12 | for (let i = 1; i < annipair.length; i++) { 13 | if (annipair[i].ctx.canvas.isConnected == false) { 14 | annipair.splice(i, 1); 15 | i--; 16 | } 17 | } 18 | 19 | annipair.forEach((v, i) => { 20 | //Generate bit 21 | if (Math.random() > (1 - annipairSettings.bitprob) * Math.min((v.data.bits.length - 5) / 5, 1)) { 22 | v.data.bits.push({ 23 | cx: v.w * 0.2 + Math.random() * v.w * 0.8, 24 | cy: v.h * 0.2 + Math.random() * v.h * 0.8, 25 | dist: v.w, 26 | dead: false 27 | }) 28 | } 29 | //clear screen 30 | v.ctx.fillStyle = "rgba(0,0,0,0.3)"; 31 | v.ctx.fillRect(0, 0, v.w, v.h); 32 | //update and draw all bits 33 | 34 | for (i = 0; i < v.data.bits.length; i++) { 35 | if (v.data.bits[i].dist > 0) { 36 | v.ctx.fillStyle = "rgb(0,100,0)"; 37 | v.ctx.fillRect(v.data.bits[i].cx - annipairSettings.r + v.data.bits[ 38 | i].dist, v.data.bits[i].cy - annipairSettings.r, 39 | 2 * annipairSettings.r, 2 * annipairSettings.r); 40 | v.ctx.fillRect(v.data.bits[i].cx - annipairSettings.r - v.data.bits[ 41 | i].dist, v.data.bits[i].cy - annipairSettings.r, 42 | 2 * annipairSettings.r, 2 * annipairSettings.r); 43 | v.data.bits[i].dist = v.w - (v.w - v.data.bits[i].dist) * 1.02 - 1; 44 | } 45 | if (v.data.bits[i].dist <= 0) { 46 | v.ctx.fillStyle = "rgb(0,255,0)"; 47 | if (!v.data.bits[i].dead) { 48 | v.data.bits[i].dead = true; 49 | v.data.bits[i].dist = -1; 50 | } 51 | v.ctx.fillRect(v.data.bits[i].cx + v.data.bits[ 52 | i].dist / 2, v.data.bits[i].cy + v 53 | .data 54 | .bits[i].dist / 2, -v.data.bits[i].dist, -v.data.bits[i].dist 55 | ); 56 | v.data.bits[i].dist--; 57 | 58 | } 59 | } 60 | while (v.data.bits.length && v.data.bits[0].dist < -10) 61 | v.data.bits.shift(); 62 | }) 63 | }, 100) 64 | 65 | return function (el) { 66 | let things; 67 | if (!el) things = document.getElementsByClassName("annipairs"); 68 | else things = [el]; 69 | for (i = 0; i < things.length; i++) { 70 | _e = things[i]; 71 | e = document.createElement("canvas"); 72 | _e.append(e); 73 | e.width = _e.clientWidth; 74 | e.height = _e.clientHeight; 75 | annipair.push({ 76 | data: { 77 | bits: [] 78 | }, 79 | ctx: e.getContext('2d'), 80 | w: e.width, 81 | h: e.height 82 | }); 83 | } 84 | } 85 | })(); -------------------------------------------------------------------------------- /src/operators/ruigen/bitstream.js: -------------------------------------------------------------------------------- 1 | ///////////////bitstream///////// 2 | bitstreams = []; 3 | bitsettings = { 4 | spacing: 1, 5 | stripcount: 6 6 | } 7 | 8 | function startBitStream(el){ 9 | let things; 10 | if (!el)things=document.getElementsByClassName("bitstream"); 11 | else things=[el]; 12 | for (i = 0; i < things.length; i++) { 13 | _e = things[i]; 14 | e = document.createElement("canvas"); 15 | _e.append(e); 16 | e.width = _e.clientWidth; 17 | e.height = _e.clientHeight; 18 | //e.height = (v.chipsize + bitsettings.spacing) * bitsettings.stripcount; 19 | //clear the screen on first run 20 | _ctx = e.getContext('2d'); 21 | _ctx.fillStyle = "black"; 22 | _ctx.fillRect(0, 0, e.clientWidth, e.clientHeight); 23 | bitstreams.push({ 24 | data: { 25 | selfc: e, 26 | pos: 0 27 | }, 28 | ctx: _ctx, 29 | chipheight: e.height / bitsettings.stripcount - bitsettings.spacing, 30 | chipwidth: e.width / bitsettings.stripcount - bitsettings.spacing, 31 | h: e.height 32 | }); 33 | } 34 | setInterval(() => { 35 | bitstreams.forEach((v, i) => { 36 | //Generate bit 37 | v.ctx.fillStyle = "rgb(0," + Math.floor(Math.random() * 255) + ",0)"; 38 | v.ctx.fillRect(bitsettings.spacing, (v.chipheight + bitsettings.spacing) * 39 | v.data.pos + 1, v.chipwidth, v.chipheight); 40 | v.data.pos++; 41 | //iterate 42 | if (v.data.pos > bitsettings.stripcount) { 43 | v.data.pos = 0; 44 | v.ctx.drawImage(v.data.selfc, v.chipwidth + bitsettings.spacing, 45 | 0); 46 | v.ctx.fillStyle = "black"; 47 | v.ctx.fillRect(0, 0, v.chipwidth + 48 | bitsettings.spacing, v.h); 49 | } 50 | }) 51 | }, 100) 52 | } 53 | if (document.readyState != "loading") startBitStream(); else document.addEventListener("DOMContentLoaded", startBitStream); -------------------------------------------------------------------------------- /src/operators/ruigen/rui_operator.js: -------------------------------------------------------------------------------- 1 | function randomRuiEl(element){ 2 | let baseurl="ruigen/"; 3 | 4 | let toLoadList=[]; 5 | let toRandomElements=document.getElementsByClassName("selectRandom"); 6 | for (let i=0;i{ 40 | this.rootdiv.innerHTML = ``; 41 | rui_op[me.settings.display](this.rootdiv); 42 | }) 43 | } 44 | 45 | //////////////////Handle polymorph_core item updates////////////////// 46 | this.refresh=function(){me.loadDisplay(me.settings.display)}; 47 | //Saving and loading 48 | this.toSaveData = function () { 49 | return this.settings; 50 | } 51 | 52 | //Handle the settings dialog click! 53 | this.dialogDiv=document.createElement("div"); 54 | this.dialogDiv.innerHTML=``; 55 | this.showDialog=function(){ 56 | // update your dialog elements with your settings 57 | } 58 | this.dialogUpdateSettings=function(){ 59 | // pull settings and update when your dialog is closed. 60 | } 61 | 62 | }); -------------------------------------------------------------------------------- /src/operators/tally.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerOperator("template", { 2 | displayName: "Template", 3 | description: "A quickstart template. Very minimal." 4 | }, function(container) { 5 | //default settings - as if you instantiated from scratch. This will merge with your existing settings from previous instatiations, facilitated by operatorTemplate. 6 | let defaultSettings = { 7 | filter: polymorph_core.guid() // used by the operator template to determine whether items are relevant to it. 8 | }; 9 | 10 | //this.rootdiv, this.settings, this.container instantiated here. 11 | polymorph_core.operatorTemplate.call(this, container, defaultSettings); 12 | 13 | //Add content-independent HTML here. 14 | this.rootdiv.innerHTML = ``; 15 | 16 | 17 | container.on("createItem", (id) => { 18 | 19 | }) 20 | 21 | container.on("deleteItem", (id) => { 22 | 23 | }) 24 | 25 | //this is called when an item is updated (e.g. by another container) 26 | container.on("updateItem", (d) => { 27 | let id = d.id; 28 | if (this.itemRelevant(id)) { 29 | //render the item, if we care about it. 30 | } 31 | //do stuff with the item. 32 | }); 33 | 34 | this.refresh = function() { 35 | // This is called when the parent container is resized. 36 | } 37 | 38 | //Handle the settings dialog click! 39 | //Handle the settings dialog click! 40 | this.dialogDiv = document.createElement("div"); 41 | this.dialogDiv.innerHTML = ``; 42 | 43 | let options = { 44 | filter: new polymorph_core._option({ 45 | div: this.dialogDiv, 46 | type: "text", 47 | object: this.settings, 48 | property: "filter", 49 | label: "Filter for items to be shown" 50 | }) 51 | //add more options here if you want -- options are managed automatically 52 | } 53 | this.showDialog = () => { 54 | //Update the settings dialog 55 | 56 | for (i in options) { 57 | options[i].load(); 58 | } 59 | } 60 | 61 | this.dialogUpdateSettings = function() { 62 | // This is called when your dialog is closed. Use it to update your container! 63 | } 64 | 65 | }); -------------------------------------------------------------------------------- /src/operators/template.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerOperator("template", { 2 | displayName: "Template", 3 | description: "A quickstart template. Very minimal." 4 | }, function (container) { 5 | //default settings - as if you instantiated from scratch. This will merge with your existing settings from previous instatiations, facilitated by operatorTemplate. 6 | let defaultSettings = { 7 | filter: polymorph_core.guid() // used by the operator template to determine whether items are relevant to it. 8 | }; 9 | 10 | //this.rootdiv, this.settings, this.container instantiated here. 11 | polymorph_core.operatorTemplate.call(this, container, defaultSettings); 12 | 13 | //Add content-independent HTML here. 14 | this.rootdiv.innerHTML = ``; 15 | 16 | container.on("createItem", (id) => { 17 | 18 | }) 19 | 20 | container.on("deleteItem", (id) => { 21 | 22 | }) 23 | 24 | //this is called when an item is updated (e.g. by another container) 25 | container.on("updateItem", (d) => { 26 | let id = d.id; 27 | if (this.itemRelevant(id)) { 28 | //render the item, if we care about it. 29 | } 30 | //do stuff with the item. 31 | }); 32 | 33 | this.refresh = function () { 34 | // This is called when the parent container is resized. 35 | } 36 | 37 | //Handle the settings dialog click! 38 | //Handle the settings dialog click! 39 | this.dialogDiv = document.createElement("div"); 40 | this.dialogDiv.innerHTML = ``; 41 | 42 | let options = { 43 | filter: new polymorph_core._option({ 44 | div: this.dialogDiv, 45 | type: "text", 46 | object: this.settings, 47 | property: "filter", 48 | label: "Filter for items to be shown" 49 | }) 50 | //add more options here if you want -- options are managed automatically 51 | } 52 | this.showDialog = () => { 53 | //Update the settings dialog 54 | 55 | for (i in options) { 56 | options[i].load(); 57 | } 58 | } 59 | 60 | this.dialogUpdateSettings = function () { 61 | // This is called when your dialog is closed. Use it to update your container! 62 | } 63 | 64 | }); -------------------------------------------------------------------------------- /src/operators/unmaintained/canvas.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerOperator("canvas", { 2 | displayName: "Canvas", 3 | description: "A canvas you can draw on." 4 | }, function (container) { 5 | let me = this; 6 | me.container = container; //not strictly compulsory bc this is expected and automatically enforced - just dont touch it pls. 7 | this.settings = {}; 8 | 9 | this.rootdiv = document.createElement("div"); 10 | //Add content-independent HTML here. fromSaveData will be called if there are any items to load. 11 | this.rootdiv.innerHTML = ``; 12 | this.canvas = this.rootdiv.querySelector("canvas"); 13 | this.ctx = this.canvas.getContext('2d'); 14 | let prex,prey; 15 | this.canvas.addEventListener("mousemove", (e) => { 16 | if (e.buttons == 1) { 17 | if (prex != undefined) { 18 | this.ctx.beginPath(); 19 | this.ctx.moveTo(prex, prey); 20 | this.ctx.lineTo(e.layerX, e.layerY); 21 | this.ctx.stroke(); 22 | this.ctx.closePath(); 23 | } 24 | 25 | } 26 | prex=e.layerX; 27 | prey=e.layerY; 28 | }) 29 | container.div.appendChild(this.rootdiv); 30 | 31 | //////////////////Handle polymorph_core item updates////////////////// 32 | 33 | //this is called when an item is updated (e.g. by another container) 34 | container.on("updateItem", function (d) { 35 | let id = d.id; 36 | //do stuff with the item. 37 | return false; 38 | }); 39 | 40 | this.rrefreshesize = function () { 41 | // This is called when my parent rect is resized. 42 | this.canvas.width=this.rootdiv.clientWidth; 43 | this.canvas.height=this.rootdiv.clientHeight; 44 | } 45 | 46 | //Saving and loading 47 | this.toSaveData = function () { 48 | return this.settings; 49 | } 50 | 51 | this.fromSaveData = function (d) { 52 | //this is called when your container is started OR your container loads for the first time 53 | Object.assign(this.settings, d); 54 | } 55 | 56 | //Handle the settings dialog click! 57 | this.dialogDiv = document.createElement("div"); 58 | this.dialogDiv.innerHTML = ``; 59 | this.showDialog = function () { 60 | // update your dialog elements with your settings 61 | } 62 | this.dialogUpdateSettings = function () { 63 | // pull settings and update when your dialog is closed. 64 | } 65 | 66 | }); -------------------------------------------------------------------------------- /src/operators/unmaintained/reference.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerOperator("template", { 2 | displayName: "Template", 3 | description: "A quickstart template. Very minimal." 4 | }, function (container) { 5 | //default settings - as if you instantiated from scratch. This will merge with your existing settings from previous instatiations, facilitated by operatorTemplate. 6 | let defaultSettings = { 7 | somesetting: "somevalue" 8 | }; 9 | 10 | //this.rootdiv, this.settings, this.container instantiated here. 11 | polymorph_core.operatorTemplate.call(this, container, defaultSettings); 12 | 13 | //Add content-independent HTML here. 14 | this.rootdiv.innerHTML = ``; 15 | 16 | //return true if we care about an item and dont want it garbage-cleaned :( 17 | 18 | this.createItem = (id) => { 19 | } 20 | 21 | this.deleteItem = (id) => { 22 | } 23 | 24 | //this is called when an item is updated (e.g. by another container) 25 | container.on("updateItem", (d) => { 26 | let id = d.id; 27 | if (this.itemRelevant(id)) { 28 | //render the item, if we care about it. 29 | } 30 | //do stuff with the item. 31 | }); 32 | 33 | this.refresh = function () { 34 | // This is called when the parent container is resized. 35 | } 36 | 37 | //Handle the settings dialog click! 38 | this.dialogDiv = document.createElement("div"); 39 | this.dialogDiv.innerHTML = ``; 40 | this.showDialog = function () { 41 | // update your dialog elements with your settings 42 | } 43 | this.dialogUpdateSettings = function () { 44 | // This is called when your dialog is closed. Use it to update your container! 45 | } 46 | 47 | }); -------------------------------------------------------------------------------- /src/operators/unmaintained/switchboard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Needs: 3 | * be aware of operators 4 | * - container handles, what kind of data they take 5 | * :: most container handles take item IDs: e.g. update, focus 6 | * :: view-change handlers take lists of items -- generally defined by other items. so technically still items. 7 | * The only thing that isnt item related is filters - which are container related. 8 | * But if we make operators = items, then voila, item based item filters! 9 | * 10 | * 11 | * There are things which describe how operators behave. These can come from within or come from other operators. 12 | * I need a way of determining where those things come from and dynamically reconfiguring them. 13 | * 14 | * three major classes though: 15 | * - string 16 | * - item pointer 17 | * - list of items 18 | * 19 | * Needs to be: 20 | * - storable in json 21 | * 22 | * possibilities: 23 | * - event api model 24 | * -- challenge: getting subscribers 25 | * -- use container.fire, and get container.fire to fire both a basic event and a specific event. 26 | * - remote function call 27 | * -- challenge: unique container ID must be assigned, even as operators are cloned, reloaded, subframed etc. 28 | * -- issue: cannot subscribe to e.g. focus events as they happen 29 | * Syntax: 30 | * @container:functionName 31 | * 32 | * Expose to users: through the wall API, as rn. Each wall will also now get buttons. 33 | * Function expected return type should match up with function actual return type. 34 | * this.parameterFunctions={ 35 | * functionName:{ 36 | * type: "string" || "itemID" || "itemList" 37 | * } 38 | * } 39 | */ -------------------------------------------------------------------------------- /src/operators/unmaintained/timer.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerOperator("timer", { 2 | displayName: "Timer", 3 | description: "A set of timers." 4 | }, function (container) { 5 | let me = this; 6 | me.container = container;//not strictly compulsory bc this is expected and automatically enforced - just dont touch it pls. 7 | this.settings = {}; 8 | 9 | this.rootdiv = document.createElement("div"); 10 | //Add content-independent HTML here. 11 | this.rootdiv.innerHTML = ``; 12 | 13 | container.div.appendChild(this.rootdiv); 14 | 15 | //////////////////Handle polymorph_core item updates////////////////// 16 | 17 | //this is called when an item is updated (e.g. by another container) 18 | container.on("updateItem", function (d) { 19 | let id = d.id; 20 | //do stuff with the item. 21 | //does it have a timer element? 22 | if (polymorph_core.items[id].timer){ 23 | //the timer should be a dateTime 24 | //if the datetime exists, then render it. 25 | //hold on, i can use the internal scripting engine to do this... 26 | } 27 | //return true or false based on whether we can or cannot edit the item from this container. 28 | //otherwise your items will be deleted by the polymorph_core garbage collector when the user saves. 29 | return false; 30 | }); 31 | 32 | this.refresh = function () { 33 | // This is called when my parent rect is resized. 34 | } 35 | 36 | //Saving and loading 37 | this.toSaveData = function () { 38 | return this.settings; 39 | } 40 | 41 | this.fromSaveData = function (d) { 42 | //this is called when your container is started OR your container loads for the first time 43 | Object.assign(this.settings, d); 44 | } 45 | 46 | //Handle the settings dialog click! 47 | this.dialogDiv=document.createElement("div"); 48 | this.dialogDiv.innerHTML=``; 49 | this.showDialog=function(){ 50 | // update your dialog elements with your settings 51 | } 52 | this.dialogUpdateSettings=function(){ 53 | // This is called when your dialog is closed. Use it to update your container! 54 | } 55 | 56 | }); -------------------------------------------------------------------------------- /src/operators/workflow/advancedentry.js: -------------------------------------------------------------------------------- 1 | function workflowy_advanced_entry() { 2 | let plaintextContenteditableRender = htmlwrap(` 3 | 4 | 5 | * 6 | 7 |   8 | 16 | 17 | `); 18 | this.plaintextContenteditableRender=plaintextContenteditableRender; 19 | let plaintextOperatingOnID; 20 | this.setShowPlaintext = (focusOnElement, event) => { 21 | if (this.settings.advancedInputMode && this.settings.isEditable) { 22 | if (focusOnElement == plaintextContenteditableRender.children[1]) { 23 | // this happens when you type \ to summon a \{} 24 | // don't update 25 | return; 26 | } else { 27 | let resolvedObject = this.resolveSpan(focusOnElement); 28 | plaintextOperatingOnID = resolvedObject.id; 29 | resolvedObject.el.insertBefore(plaintextContenteditableRender, resolvedObject.el.children[1]); 30 | plaintextContenteditableRender.children[1].innerText = polymorph_core.items[plaintextOperatingOnID][this.settings.titleProperty]; 31 | // send a click event to a few px below, which will cause us to focus in the right place 32 | // let shiftedEvent = new PointerEvent(event.type); 33 | // for (let i in event) { 34 | // try { 35 | // shiftedEvent[i] = event[i] 36 | // } catch (e) {} 37 | // } 38 | // shiftedEvent.clientY += 10; 39 | // shiftedEvent.screenY += 10; 40 | // shiftedEvent.pageY += 10; 41 | // this.rootdiv.dispatchEvent(shiftedEvent); 42 | plaintextContenteditableRender.children[1].focus(); 43 | } 44 | } else { 45 | plaintextContenteditableRender.remove(); 46 | } 47 | } 48 | plaintextContenteditableRender.addEventListener("input", (e) => { 49 | this.parse(e.target, plaintextOperatingOnID); 50 | polymorph_core.items[plaintextOperatingOnID][this.settings.titleProperty] = e.target.innerText; // polymorph_core.RTParseElement(e.target, id, this.settings.titleProperty); 51 | this.container.fire("updateItem", { id: plaintextOperatingOnID, sender: this }); 52 | this.renderItem(plaintextOperatingOnID, "d"); 53 | }); 54 | } -------------------------------------------------------------------------------- /src/operators/workflow/focusMode.js: -------------------------------------------------------------------------------- 1 | function _workflow_focusMode_extend() { 2 | this.container.on("metaFocus", (d) => { 3 | if (this.settings.focusExclusionMode && this.itemRelevant(d.id)) { 4 | this.settings.focusExclusionID = d.id; 5 | this.focusModeRefresh(); 6 | } 7 | }); 8 | let bannedSign = htmlwrap(`

    Fire an attached metaFocus to use this operator in the focusExclusion mode.

    `); 9 | this.focusModeRefresh = () => { 10 | if (this.settings.focusExclusionMode) { 11 | // Remove everything from the board 12 | while (this.innerRoot.children.length) { 13 | this.innerRoot.children[0].remove(); 14 | } 15 | // Render this particular item as root, and all of its children 16 | // Special provision to prevent enter on root-1 item (the focused one so canot create root items) 17 | if (this.settings.focusExclusionID) { 18 | bannedSign.remove(); 19 | for (let i in polymorph_core.items) { 20 | this.renderItem(i, "pd"); // dont reorganise parent here 21 | } 22 | } else { 23 | this.innerRoot.appendChild(bannedSign); 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/operators/workflow/search.js: -------------------------------------------------------------------------------- 1 | function workflowy_gitfriendly_search() { 2 | this.holdExpanded = {}; 3 | this.rootdiv.querySelector(".searcher").addEventListener("keyup", (e) => { 4 | //hide all items 5 | this.holdExpanded = {}; 6 | if (e.target.value.length > 2) { 7 | // Hide everything 8 | for (let i in this.renderedItemCache) { 9 | if (i) { 10 | if (this.settings.filterHides) this.resolveSpan(i).el.style.display = "none"; 11 | this.resolveSpan(i).el.classList.remove("searchFocused"); 12 | //rerender to hide the ones we dont want 13 | this.renderItem(i, "pdf"); 14 | } 15 | } 16 | for (let i in polymorph_core.items) { 17 | // If the node has the text we want 18 | if (this.itemRelevant(i) && polymorph_core.items[i][this.settings.titleProperty].toLowerCase().includes(e.target.value.toLowerCase())) { 19 | // Gather its parents 20 | let ptree = [i]; 21 | let p = i; 22 | while (polymorph_core.items[p][this.settings.parentProperty]) { 23 | p = polymorph_core.items[p][this.settings.parentProperty]; 24 | ptree.unshift(p); 25 | if (!this.itemRelevant(p)) { 26 | ptree = []; 27 | break; 28 | }; 29 | } 30 | // Force render all its parents 31 | ptree.forEach((v, i) => { 32 | // force render it 33 | this.renderItem(v, "pdf"); 34 | let el = this.renderedItemCache[v].el; 35 | el.style.display = "block"; 36 | if (i == ptree.length - 1) { 37 | el.classList.add("searchFocused"); 38 | } 39 | if (i != ptree.length - 1 || this.holdExpanded[v]) { 40 | this.holdExpanded[v] = true; 41 | this.setExpandedState(el, true, true, true); 42 | } 43 | // set it to expanded 44 | // unless it's the last one 45 | }); 46 | // also show all parents (but don't expand?) 47 | } 48 | } 49 | } else { 50 | for (let i in this.renderedItemCache) { 51 | if (i) { 52 | this.renderItem(i, "d"); 53 | this.renderedItemCache[i].el.style.display = "block"; 54 | this.renderedItemCache[i].el.classList.remove("searchFocused"); 55 | } 56 | } 57 | } 58 | //show selected items 59 | //v comp expense! use cache if too hard 60 | }) 61 | } -------------------------------------------------------------------------------- /src/operators/workflow/workflow tests.md: -------------------------------------------------------------------------------- 1 | Observations: 2 | - if we tie the toorder to the item, multiple additions will overwrite, resulting in loss of items 3 | - this could be fixed by merging the lists 4 | - if we were to merge the lists, we would do so by levinstein distance 5 | - we could make each item remember who their previous sibling was and their parent sibling is 6 | - but if two middle siblings are deleted then RIP 7 | - make each item remember their parent and an ordering index 8 | - items can be added, deleted, rendered, unshifted (= deleted and added to parent) 9 | 10 | 11 | Workflow tests 12 | 13 | enter on root item creates new item below current item (root / child) 14 | up and down change focus to previous item. 15 | 16 | alt up and alt down to rearrange items 17 | 18 | 19 | === TODO === 20 | deal with the cursor span being a derp 21 | 22 | ============== Workflow Gitfriendly ============= 23 | - every item has a parent and a number 24 | - number starts from 0 and goes up 25 | - if there is a conflict then the item with the smaller ID goes first, and then a reordering is done 26 | - if the parent is nothing then it is a rootelement -------------------------------------------------------------------------------- /src/operators/workflow/workflow.phonebar.sticky.js: -------------------------------------------------------------------------------- 1 | function workflowy_stick(el){ 2 | var viewport = window.visualViewport; 3 | const layoutSpanner = document.createElement("div"); 4 | 5 | document.body.appendChild(layoutSpanner); 6 | 7 | layoutSpanner.style.position="fixed"; 8 | layoutSpanner.style.width="100%"; 9 | layoutSpanner.style.height="100%"; 10 | layoutSpanner.style.visibility="hidden"; 11 | 12 | function viewportHandler() { 13 | // Since the bar is position: fixed we need to offset it by the visual 14 | // viewport's offset from the layout viewport origin. 15 | var offsetX = viewport.offsetLeft; 16 | var offsetY = viewport.height 17 | - layoutSpanner.getBoundingClientRect().height 18 | + viewport.offsetTop; 19 | 20 | // You could also do this by setting style.left and style.top if you 21 | // use width: 100% instead. 22 | el.style.transform = 'translate(' + 23 | offsetX + 'px,' + 24 | offsetY + 'px) ' + 25 | 'scale(' + 1/viewport.scale + ')' 26 | } 27 | window.visualViewport.addEventListener('scroll', viewportHandler); 28 | window.visualViewport.addEventListener('resize', viewportHandler); 29 | } -------------------------------------------------------------------------------- /src/operators/workflow/workflow_recursive_paste.js: -------------------------------------------------------------------------------- 1 | let workflow_recursive_paste = function () { 2 | const mappings = ["parentProperty","orderProperty","titleProperty","filter"]; 3 | 4 | this.check_workflow_recursive_paste = (text, rootID) => { 5 | if (text.startsWith("__WORKFLOWY_IMPORT__")) { 6 | try { 7 | const jsonData = JSON.parse(text.slice("__WORKFLOWY_IMPORT__".length)); 8 | // This will be a dict of items 9 | // Create the new items with new IDs 10 | let oldID_newID_map = {}; 11 | for (let oldID in jsonData.items) { 12 | let newID = this.createItem(); 13 | oldID_newID_map[oldID] = newID; 14 | // Remap the properties 15 | mappings.forEach(property=>{ 16 | polymorph_core.items[newID][this.settings[property]] = jsonData.items[oldID][property]; 17 | }) 18 | 19 | 20 | } 21 | for (let oldID in jsonData.items){ 22 | // Extra remapping for fromProperty 23 | currentNewID=oldID_newID_map[oldID]; 24 | if (currentNewID == oldID_newID_map[jsonData.rootID]){ 25 | // Assign root level parent to current span ID 26 | polymorph_core.items[currentNewID][this.settings.parentProperty] = rootID; 27 | }else{ 28 | polymorph_core.items[currentNewID][this.settings.parentProperty]=oldID_newID_map[polymorph_core.items[currentNewID][this.settings.parentProperty]]; 29 | } 30 | polymorph_core.fire("updateItem",{id: currentNewID, sender: this}); 31 | this.renderItem(currentNewID) 32 | } 33 | return true; 34 | } catch (e) { 35 | return false; 36 | } 37 | } else { 38 | return false; 39 | } 40 | } 41 | 42 | this.copylistExternal=(e) => { 43 | let mappingsArray = ["parentProperty","orderProperty","titleProperty","filter"]; 44 | const sublistAsJSON = { 45 | rootID: this.contextTarget.dataset.id, 46 | items: {} 47 | } 48 | 49 | 50 | let runStack = [this.contextTarget]; 51 | while (runStack.length) { 52 | let top = runStack.pop(); 53 | let filteredItem = {}; 54 | mappingsArray.forEach(setting=>{ 55 | filteredItem[setting]=polymorph_core.items[top.dataset.id][this.settings[setting]]; 56 | }) 57 | sublistAsJSON.items[top.dataset.id]=filteredItem; 58 | let childItemDiv = top.children[top.children.length - 1]; // not just 1, becuase of the rich edit mode. but always last 59 | for (let i = childItemDiv.children.length - 1; i >= 0; i--) { 60 | runStack.push(childItemDiv.children[i]); 61 | } 62 | } 63 | 64 | this.copyToClipboard("__WORKFLOWY_IMPORT__" + JSON.stringify(sublistAsJSON)); 65 | return true; 66 | } 67 | } -------------------------------------------------------------------------------- /src/operators/workflow/workflow_shim.js: -------------------------------------------------------------------------------- 1 | // todo: on enter or defocus, create new item 2 | // tab to indent 3 | polymorph_core.registerOperator("workflow", { 4 | displayName: "Workflowish", 5 | description: "Nested, plaintext lists. Workflowy emulation. Auto-upgrades to newest workflow.", 6 | section: "Standard", 7 | imageurl: "assets/operators/wkflow.PNG", 8 | hidden: true 9 | }, function(container) { 10 | polymorph_core.items[container.id]._od.t = "workflow_gf"; 11 | let pc = new polymorph_core.operators["workflow_gf"](container); 12 | pc.doImport(container.id); 13 | return pc; 14 | }); -------------------------------------------------------------------------------- /src/saveSources/lobby.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerSaveSource("lobby", function(save_source_data) { 2 | // redirect to server 3 | return new polymorph_core.saveSources["srv"](save_source_data); 4 | }, { 5 | prettyName: "Save to local lobby", 6 | createable: true 7 | }) -------------------------------------------------------------------------------- /src/saveSources/localforage2.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerSaveSource("lf", function(save_source_data) { // a sample save source, implementing a number of functions. 2 | polymorph_core.saveSourceTemplate.call(this, save_source_data); 3 | 4 | this.pushAll = async function(data) { 5 | localforage.setItem("__polymorph_" + polymorph_core.currentDocID, data).then(() => { 6 | polymorph_core.saved_until = Date.now(); 7 | polymorph_core.showNotification('Localforage Saved', 'success'); 8 | }); 9 | //used by user to force push. 10 | } 11 | this.pullAll = async function() { 12 | let d = await localforage.getItem("__polymorph_" + save_source_data.data.id); 13 | return d; 14 | } 15 | 16 | this.dialog = document.createElement("div"); 17 | this.dialog.innerHTML = ` 18 | 19 | 20 | 21 | `; 22 | this.showDialog = () => { 23 | if (!save_source_data.data.id) save_source_data.data.id = polymorph_core.currentDocID; 24 | this.dialog.querySelector(".svid").value = save_source_data.data.id; 25 | } 26 | 27 | this.dialog.querySelector(".svid").addEventListener("input", (e) => { 28 | save_source_data.data.id = e.target.value; 29 | }) 30 | 31 | polymorph_core.addToSaveDialog(this); 32 | 33 | this.hook = async() => { 34 | //hook to pull changes and push changes. 35 | //To subscribe to live updates, you need to manually use polymorph_core.on("updateItem",handler) to listen to item updates. 36 | //Otherwise, you can subscribe to the user save event, as per below, and set a flag to remind yourself to save 37 | this.toSave = true; 38 | } 39 | 40 | polymorph_core.on("userSave", (d) => { 41 | if (save_source_data.save) { 42 | this.pushAll(d); 43 | return true; //return true if we save 44 | } else { 45 | return false; 46 | } 47 | }) 48 | 49 | // Please remove or comment out this function if you can't subscribe to live updates. 50 | this.unhook = async() => { 51 | //unhook previous hooks. 52 | this.toSave = false; 53 | } 54 | }, { 55 | createable: true, 56 | prettyName: "Localforage (offline storage)" 57 | }) -------------------------------------------------------------------------------- /src/saveSources/permalink.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerSaveSource("permalink", function(save_source_data) { 2 | //special permalink operator: for when i want to create a permalink to a doc. 3 | 4 | //fetches JSON from an XHR that is embedded in the url in base64 format. 5 | 6 | polymorph_core.saveSourceTemplate.call(this, save_source_data); 7 | //initialise here 8 | //id, source 9 | 10 | this.pullAll = async function() { 11 | let d = save_source_data.data; 12 | return d; 13 | } 14 | 15 | }, { 16 | prettyName: "Permalink", 17 | createable: false, 18 | canHandle: async(params) => { 19 | return new Promise((res, rej) => { 20 | if (params.has("pml")) { 21 | var xmlhttp = new XMLHttpRequest(); 22 | let url = atob(params.get("pml")); 23 | xmlhttp.open('GET', url, true); 24 | xmlhttp.onreadystatechange = function() { 25 | if (xmlhttp.readyState == 4) { 26 | if (xmlhttp.status == 200) { 27 | try { 28 | var obj = JSON.parse(xmlhttp.responseText); 29 | let tempID = polymorph_core.guid(6, polymorph_core.userData.documents); 30 | obj = polymorph_core.datautils.decompress(obj); 31 | obj._meta.id = tempID; 32 | res({ id: tempID, data: obj }); 33 | } catch (e) { 34 | res(false); 35 | } 36 | } else { 37 | res(false); 38 | } 39 | } 40 | }; 41 | xmlhttp.send(null); 42 | } else { 43 | res(false); 44 | } 45 | }) 46 | } 47 | }) -------------------------------------------------------------------------------- /src/saveSources/template.js: -------------------------------------------------------------------------------- 1 | polymorph_core.registerSaveSource("template", function(save_source_data) { // a sample save source, implementing a number of functions. 2 | polymorph_core.saveSourceTemplate.call(this, save_source_data); //future-safety measure. sets this.settings to save_source_data. 3 | //initialise here 4 | // Set pretty name and creatability at end of file. 5 | 6 | 7 | //for the actual display: 8 | this.dialog = document.createElement("div"); 9 | this.dialog.innerHTML = `whatever`; 10 | polymorph_core.addToSaveDialog(this); 11 | this.showDialog = () => { 12 | //do something 13 | } 14 | 15 | 16 | //optional function: given a set of urlparams, can you handle opening the file? If no, return false, do not implement, or delete. 17 | this.canHandle = function(params) { 18 | //if you return true, be prepared to handle id as a set of urlparams instead. 19 | //at which point, please do what you need to do to initialise, then return {id: name_of_doc, source:data_you_need_to_load} 20 | } 21 | 22 | //ID will be a string if the object is loaded; otherwise a custom object that you have set in the past 23 | //Set custom objects by using polymorph_core.userData.documents[polymorph_core.currentDocID].saveSources['your_savesource_name']. 24 | 25 | this.pushAll = async function(data) { 26 | //push to the source (force save) 27 | } 28 | this.pullAll = async function() { 29 | return object_with_data; //or nothing, if undefined 30 | } 31 | 32 | this.hook = async function() { 33 | //hook to pull changes and push changes. 34 | //To subscribe to live updates, you need to manually use polymorph_core.on("updateItem",handler) to listen to item updates. 35 | //Otherwise, you can subscribe to the user save event, as per below, and set a flag to remind yourself to save 36 | this.toSave = true; 37 | } 38 | 39 | 40 | // Please remove or comment out this function if you can't subscribe to live updates. 41 | this.unhook = async function(id) { 42 | //unhook previous hooks. 43 | this.toSave = false; 44 | } 45 | 46 | polymorph_core.on("userSave", (d) => { 47 | if (this.toSave) { 48 | this.pushAll(d); 49 | return true; //return true if we save 50 | } else { 51 | return false; 52 | } 53 | }) 54 | 55 | window.addEventListener("beforeunload", () => { 56 | 57 | }) 58 | }, { 59 | prettyName: "Save to server", 60 | createable: true 61 | }) -------------------------------------------------------------------------------- /src/unit_core.js: -------------------------------------------------------------------------------- 1 | {// Simple Block for closure 2 | 3 | // Hack polymorph_core to replace some of the registration functions so we immediately load the operator and savesource 4 | polymorph_core.start = function (userSave) { 5 | this.resetDocument(); 6 | let debugUserSave = localStorage.getItem("__unitcore_debug_from"); 7 | if (debugUserSave) { 8 | userSave = JSON.parse(debugUserSave); 9 | } 10 | } 11 | 12 | 13 | // Load the savesource and operator if not in debug mode 14 | let debugOperator = localStorage.getItem("__unitcore_debug_operator"); 15 | if (debugOperator) { 16 | appendScript(debugOperator); 17 | } else { 18 | appendScript("operator.js"); 19 | } 20 | let debugSavesource = localStorage.getItem("__unitcore_debug_savesource"); 21 | if (debugSavesource) { 22 | appendScript(debugSavesource); 23 | } else { 24 | appendScript("savesource.js"); 25 | } 26 | } --------------------------------------------------------------------------------