├── savetable ├── ext.manifest ├── api │ └── savetable.script_api └── src │ └── main.cpp ├── .lua-format ├── .clang-format ├── .gitignore ├── example ├── example.font ├── example.script └── example.collection ├── game.project ├── .gitattributes ├── README.md └── LICENSE.md /savetable/ext.manifest: -------------------------------------------------------------------------------- 1 | name: "savetable" 2 | -------------------------------------------------------------------------------- /.lua-format: -------------------------------------------------------------------------------- 1 | column_limit: 120 2 | keep_simple_control_block_one_line: false 3 | keep_simple_function_one_line: false 4 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: LLVM 3 | ColumnLimit: 120 4 | IncludeBlocks: Regroup 5 | IndentWidth: 4 6 | TabWidth: 4 7 | 8 | ... 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.internal 2 | /build 3 | .externalToolBuilders 4 | .DS_Store 5 | Thumbs.db 6 | .lock-wscript 7 | *.pyc 8 | .project 9 | .cproject 10 | builtins 11 | /editor-script-lua-format 12 | /.vscode 13 | -------------------------------------------------------------------------------- /example/example.font: -------------------------------------------------------------------------------- 1 | font: "/builtins/fonts/vera_mo_bd.ttf" 2 | material: "/builtins/fonts/font-df.material" 3 | size: 28 4 | antialias: 1 5 | alpha: 1.0 6 | outline_alpha: 0.0 7 | outline_width: 0.0 8 | shadow_alpha: 0.0 9 | shadow_blur: 0 10 | shadow_x: 0.0 11 | shadow_y: 0.0 12 | extra_characters: "" 13 | output_format: TYPE_DISTANCE_FIELD 14 | all_chars: false 15 | cache_width: 0 16 | cache_height: 0 17 | render_mode: MODE_SINGLE_LAYER 18 | -------------------------------------------------------------------------------- /game.project: -------------------------------------------------------------------------------- 1 | [bootstrap] 2 | main_collection = /example/example.collectionc 3 | 4 | [script] 5 | shared_state = 1 6 | 7 | [display] 8 | width = 640 9 | height = 960 10 | high_dpi = 1 11 | 12 | [project] 13 | title = savetable 14 | version = 1.0.0 15 | developer = Indiesoft LLC 16 | 17 | [library] 18 | include_dirs = savetable 19 | 20 | [render] 21 | clear_color_alpha = 1.0 22 | clear_color_blue = 0.1 23 | clear_color_red = 0.1 24 | clear_color_green = 0.1 25 | 26 | [android] 27 | package = com.splitmix64.example 28 | 29 | [html5] 30 | scale_mode = fit 31 | 32 | [input] 33 | game_binding = /builtins/input/all.input_bindingc 34 | 35 | -------------------------------------------------------------------------------- /savetable/api/savetable.script_api: -------------------------------------------------------------------------------- 1 | - name: savetable 2 | type: table 3 | desc: Serialize/deserialize Lua tables in Defold. 4 | members: 5 | 6 | - name: serialize 7 | type: function 8 | parameters: 9 | - name: table 10 | type: table 11 | - name: max_memory_bytes 12 | type: number 13 | optional: true 14 | returns: 15 | - name: encoded_table 16 | type: string 17 | 18 | - name: deserialize 19 | type: function 20 | parameters: 21 | - name: encoded_table 22 | type: string 23 | returns: 24 | - name: result 25 | type: table 26 | 27 | - name: encode_base64 28 | type: function 29 | parameters: 30 | - name: input 31 | type: string 32 | return: 33 | - name: output 34 | type: string 35 | 36 | - name: decode_base64 37 | type: function 38 | parameters: 39 | - name: input 40 | type: string 41 | return: 42 | - name: output 43 | type: string 44 | -------------------------------------------------------------------------------- /example/example.script: -------------------------------------------------------------------------------- 1 | local TINT_GREEN = vmath.vector4(0.3, 0.9, 0.3, 1) 2 | local TINT_RED = vmath.vector4(0.9, 0.3, 0.3, 1) 3 | 4 | local function equal_str(actual, expected, label_url) 5 | if actual == expected then 6 | label.set_text(label_url, tostring(actual) .. " ==\n" .. tostring(expected)) 7 | go.set(label_url, "color", TINT_GREEN) 8 | else 9 | label.set_text(label_url, tostring(actual) .. " ~=\n" .. tostring(expected)) 10 | go.set(label_url, "color", TINT_RED) 11 | end 12 | end 13 | 14 | function init(self) 15 | msg.post("@render:", "use_fixed_fit_projection", { near = -1, far = 1 }) 16 | 17 | print("Base64 'world' encoded is", savetable.encode_base64("world")) 18 | print("Empty table {} is", savetable.encode_base64(savetable.serialize({}))) 19 | 20 | local t = { hello = "world" } 21 | local s = savetable.encode_base64(savetable.serialize(t, 1024)) 22 | local t2 = savetable.deserialize(savetable.decode_base64(s)) 23 | 24 | equal_str(s, "SERUQgMAAAABAAQEBQAAAGhlbGxvBQAAAHdvcmxk", "/tests#test1") 25 | equal_str(t.hello, t2.hello, "/tests#test2") 26 | 27 | local big_table = {} 28 | for i = 1, 50000 do 29 | table.insert(big_table, { data = i }) 30 | end 31 | local s = savetable.serialize(big_table, 4 * 1024 * 1024) 32 | print("Size", #s) 33 | local t2 = savetable.deserialize(s) 34 | for i = 1, 50000 do 35 | assert(t2[i].data == i) 36 | end 37 | print("OK") 38 | end 39 | 40 | function update(self, dt) 41 | end 42 | 43 | function on_message(self, message_id, message, sender) 44 | end -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Defold Protocol Buffer Text Files (https://github.com/github/linguist/issues/5091) 2 | *.animationset linguist-language=JSON5 gitlab-language=protobuf 3 | *.atlas linguist-language=JSON5 gitlab-language=protobuf 4 | *.camera linguist-language=JSON5 gitlab-language=protobuf 5 | *.collection linguist-language=JSON5 gitlab-language=protobuf 6 | *.collectionfactory linguist-language=JSON5 gitlab-language=protobuf 7 | *.collectionproxy linguist-language=JSON5 gitlab-language=protobuf 8 | *.collisionobject linguist-language=JSON5 gitlab-language=protobuf 9 | *.cubemap linguist-language=JSON5 gitlab-language=protobuf 10 | *.display_profiles linguist-language=JSON5 gitlab-language=protobuf 11 | *.factory linguist-language=JSON5 gitlab-language=protobuf 12 | *.font linguist-language=JSON5 gitlab-language=protobuf 13 | *.gamepads linguist-language=JSON5 gitlab-language=protobuf 14 | *.go linguist-language=JSON5 gitlab-language=protobuf 15 | *.gui linguist-language=JSON5 gitlab-language=protobuf 16 | *.input_binding linguist-language=JSON5 gitlab-language=protobuf 17 | *.label linguist-language=JSON5 gitlab-language=protobuf 18 | *.material linguist-language=JSON5 gitlab-language=protobuf 19 | *.mesh linguist-language=JSON5 gitlab-language=protobuf 20 | *.model linguist-language=JSON5 gitlab-language=protobuf 21 | *.particlefx linguist-language=JSON5 gitlab-language=protobuf 22 | *.render linguist-language=JSON5 gitlab-language=protobuf 23 | *.sound linguist-language=JSON5 gitlab-language=protobuf 24 | *.sprite linguist-language=JSON5 gitlab-language=protobuf 25 | *.spinemodel linguist-language=JSON5 gitlab-language=protobuf 26 | *.spinescene linguist-language=JSON5 gitlab-language=protobuf 27 | *.texture_profiles linguist-language=JSON5 gitlab-language=protobuf 28 | *.tilemap linguist-language=JSON5 gitlab-language=protobuf 29 | *.tilesource linguist-language=JSON5 gitlab-language=protobuf 30 | 31 | # Defold JSON Files 32 | *.buffer linguist-language=JSON gitlab-language=json 33 | 34 | # Defold GLSL Shaders 35 | *.fp text eol=lf linguist-language=GLSL gitlab-language=glsl 36 | *.vp text eol=lf linguist-language=GLSL gitlab-language=glsl 37 | 38 | # Defold Lua Files 39 | *.editor_script text eol=lf linguist-language=Lua gitlab-language=lua 40 | *.render_script text eol=lf linguist-language=Lua gitlab-language=lua 41 | *.script text eol=lf linguist-language=Lua gitlab-language=lua 42 | *.gui_script text eol=lf linguist-language=Lua gitlab-language=lua 43 | 44 | # Defold Project Settings 45 | *.project linguist-language=INI gitlab-language=ini 46 | 47 | # EOL Settings 48 | *.cpp text eol=lf 49 | *.html text eol=lf 50 | *.json text eol=lf 51 | *.lua text eol=lf 52 | *.md text eol=lf 53 | *.yml text eol=lf 54 | -------------------------------------------------------------------------------- /savetable/src/main.cpp: -------------------------------------------------------------------------------- 1 | #define LIB_NAME "savetable" 2 | #define MODULE_NAME "savetable" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace dmScript { 11 | uint32_t CheckTable(lua_State *L, char *buffer, uint32_t buffer_size, int index); 12 | void PushTable(lua_State *L, const char *buffer, uint32_t buffer_size); 13 | } // namespace dmScript 14 | 15 | static int Serialize(lua_State *L) { 16 | luaL_checktype(L, 1, LUA_TTABLE); 17 | 18 | int buflen = 512 * 1024; 19 | if (lua_isnumber(L, 2)) { 20 | buflen = lua_tonumber(L, 2); 21 | } 22 | char *buf = (char *)malloc(buflen); 23 | uint32_t n_used = dmScript::CheckTable(L, buf, buflen, 1); 24 | 25 | lua_pushlstring(L, (char *)buf, n_used); 26 | free(buf); 27 | return 1; 28 | } 29 | 30 | static int Deserialize(lua_State *L) { 31 | size_t srclen; 32 | const char* src = luaL_checklstring(L, 1, &srclen); 33 | 34 | dmScript::PushTable(L, src, srclen); 35 | return 1; 36 | } 37 | 38 | static int Encode_Base64(lua_State* L) 39 | { 40 | size_t srclen; 41 | const char* src = luaL_checklstring(L, 1, &srclen); 42 | 43 | uint32_t dstlen = srclen * 4 / 3 + 4; 44 | uint8_t* dst = (uint8_t*)malloc(dstlen); 45 | if (!dmCrypt::Base64Encode((uint8_t *)src, srclen, dst, &dstlen)) { 46 | free(dst); 47 | return luaL_error(L, "Can't encode data into Base64 string."); 48 | } 49 | 50 | lua_pushlstring(L, (char *)dst, dstlen); 51 | free(dst); 52 | return 1; 53 | } 54 | 55 | static int Decode_Base64(lua_State* L) 56 | { 57 | size_t srclen; 58 | const char* src = luaL_checklstring(L, 1, &srclen); 59 | 60 | uint32_t dstlen = srclen * 3 / 4; 61 | uint8_t* dst = (uint8_t*)malloc(dstlen); 62 | if (!dmCrypt::Base64Decode((const uint8_t*)src, srclen, dst, &dstlen)) 63 | { 64 | free(dst); 65 | return luaL_error(L, "Can't decode Base64 string."); 66 | } 67 | 68 | lua_pushlstring(L, (char*)dst, dstlen); 69 | free(dst); 70 | return 1; 71 | } 72 | 73 | // Functions exposed to Lua 74 | static const luaL_reg Module_methods[] = { 75 | {"serialize", Serialize}, 76 | {"deserialize", Deserialize}, 77 | // Base64 78 | {"encode_base64", Encode_Base64}, 79 | {"decode_base64", Decode_Base64}, 80 | /* Sentinel: */ 81 | {NULL, NULL}}; 82 | 83 | static void LuaInit(lua_State *L) { 84 | int top = lua_gettop(L); 85 | 86 | // Register lua names 87 | luaL_register(L, MODULE_NAME, Module_methods); 88 | 89 | lua_pop(L, 1); 90 | assert(top == lua_gettop(L)); 91 | } 92 | 93 | static dmExtension::Result InitializeExtension(dmExtension::Params *params) { 94 | LuaInit(params->m_L); 95 | return dmExtension::RESULT_OK; 96 | } 97 | 98 | DM_DECLARE_EXTENSION(savetable, LIB_NAME, 0, 0, InitializeExtension, 0, 0, 0) 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SaveTable 2 | 3 | ⚠️ Defold has implemented [`sys.serialize()`/`sys.deserialize()`](https://defold.com/ref/beta/sys/#sys.serialize:table) since version 1.2.188. Use the new functions instead of this extension. ⚠️ 4 | 5 | ## Description 6 | 7 | This asset allows you to serialize/deserialize Lua tables in Defold the same way as it does via `sys.save`/`sys.load`. The limits are the same: 8 | 9 | > Internally, this function uses a workspace buffer sized output file sized 512kb. This size reflects the output file size which must not exceed this limit. Additionally, the total number of rows that any one table may contain is limited to 65536 (i.e. a 16 bit range). When tables are used to represent arrays, the values of keys are permitted to fall within a 32 bit range, supporting sparse arrays, however the limit on the total number of rows remains in effect. 10 | 11 | ## Installation 12 | 13 | Use it in your own project by adding this project as a [Defold library dependency](http://www.defold.com/manuals/libraries/). Open your `game.project` file and in the dependencies field under project add: 14 | 15 | https://github.com/aglitchman/defold-savetable/archive/main.zip 16 | 17 | ## Usage 18 | 19 | ```lua 20 | local tbl = { example = true } 21 | 22 | -- Encode Lua table into a base64-encoded string 23 | local str = savetable.encode_base64(savetable.serialize(tbl)) 24 | print(str) 25 | 26 | -- Decode Lua table from a string 27 | local tbl2 = savetable.deserialize(savetable.decode_base64(str)) 28 | pprint(tbl2) 29 | ``` 30 | 31 | ### How to use it in [DefSave](https://github.com/subsoap/defsave) for HTML5 builds 32 | 33 | `defsave/defsave.lua`, replace lines 124-131 with: 34 | 35 | ```lua 36 | local loaded_file 37 | if html5 then 38 | -- sys.load can't be used for HTML5 apps running on iframe from a different origin (cross-origin iframe) 39 | -- use `localStorage` instead because of this limitation on default IndexedDB storage used by Defold 40 | local EMPTY_TABLE = savetable.encode_base64(savetable.serialize({})) 41 | loaded_file = savetable.deserialize(savetable.decode_base64(html5.run([[(function(){try{return window.localStorage.getItem(']] .. path .. [[')||']] .. EMPTY_TABLE .. [['}catch(e){return']] .. EMPTY_TABLE .. [['}})()]]))) 42 | else 43 | loaded_file = sys.load(path) 44 | end 45 | ``` 46 | 47 | `defsave/defsave.lua`, replace lines 183-194 with: 48 | 49 | ```lua 50 | local is_save_successful 51 | if html5 then 52 | -- sys.save can't be used for HTML5 apps running on iframe from a different origin (cross-origin iframe) 53 | -- use `localStorage` instead because of this limitation on default IndexedDB storage used by Defold 54 | local encoded_data = savetable.encode_base64(savetable.serialize(M.loaded[file].data)) 55 | html5.run([[try{window.localStorage.setItem(']] .. path .. [[', ']] .. encoded_data .. [[')}catch(e){}]]) 56 | 57 | is_save_successful = true 58 | else 59 | is_save_successful = sys.save(path, M.loaded[file].data) 60 | end 61 | ``` 62 | 63 | ## Credits 64 | 65 | This project is licensed under the terms of the CC0 1.0 Universal license. 66 | -------------------------------------------------------------------------------- /example/example.collection: -------------------------------------------------------------------------------- 1 | name: "main" 2 | scale_along_z: 0 3 | embedded_instances { 4 | id: "go" 5 | data: "components {\n" 6 | " id: \"example\"\n" 7 | " component: \"/example/example.script\"\n" 8 | " position {\n" 9 | " x: 0.0\n" 10 | " y: 0.0\n" 11 | " z: 0.0\n" 12 | " }\n" 13 | " rotation {\n" 14 | " x: 0.0\n" 15 | " y: 0.0\n" 16 | " z: 0.0\n" 17 | " w: 1.0\n" 18 | " }\n" 19 | "}\n" 20 | "" 21 | position { 22 | x: 0.0 23 | y: 0.0 24 | z: 0.0 25 | } 26 | rotation { 27 | x: 0.0 28 | y: 0.0 29 | z: 0.0 30 | w: 1.0 31 | } 32 | scale3 { 33 | x: 1.0 34 | y: 1.0 35 | z: 1.0 36 | } 37 | } 38 | embedded_instances { 39 | id: "tests" 40 | data: "embedded_components {\n" 41 | " id: \"title\"\n" 42 | " type: \"label\"\n" 43 | " data: \"size {\\n" 44 | " x: 320.0\\n" 45 | " y: 32.0\\n" 46 | " z: 0.0\\n" 47 | " w: 0.0\\n" 48 | "}\\n" 49 | "scale {\\n" 50 | " x: 2.0\\n" 51 | " y: 2.0\\n" 52 | " z: 2.0\\n" 53 | " w: 0.0\\n" 54 | "}\\n" 55 | "color {\\n" 56 | " x: 1.0\\n" 57 | " y: 1.0\\n" 58 | " z: 1.0\\n" 59 | " w: 1.0\\n" 60 | "}\\n" 61 | "outline {\\n" 62 | " x: 0.0\\n" 63 | " y: 0.0\\n" 64 | " z: 0.0\\n" 65 | " w: 1.0\\n" 66 | "}\\n" 67 | "shadow {\\n" 68 | " x: 0.0\\n" 69 | " y: 0.0\\n" 70 | " z: 0.0\\n" 71 | " w: 1.0\\n" 72 | "}\\n" 73 | "leading: 1.0\\n" 74 | "tracking: 0.0\\n" 75 | "pivot: PIVOT_CENTER\\n" 76 | "blend_mode: BLEND_MODE_ALPHA\\n" 77 | "line_break: false\\n" 78 | "text: \\\"SaveTable\\\"\\n" 79 | "font: \\\"/example/example.font\\\"\\n" 80 | "material: \\\"/builtins/fonts/label-df.material\\\"\\n" 81 | "\"\n" 82 | " position {\n" 83 | " x: 0.0\n" 84 | " y: 206.0\n" 85 | " z: 0.0\n" 86 | " }\n" 87 | " rotation {\n" 88 | " x: 0.0\n" 89 | " y: 0.0\n" 90 | " z: 0.0\n" 91 | " w: 1.0\n" 92 | " }\n" 93 | "}\n" 94 | "embedded_components {\n" 95 | " id: \"test1\"\n" 96 | " type: \"label\"\n" 97 | " data: \"size {\\n" 98 | " x: 640.0\\n" 99 | " y: 32.0\\n" 100 | " z: 0.0\\n" 101 | " w: 0.0\\n" 102 | "}\\n" 103 | "scale {\\n" 104 | " x: 0.65\\n" 105 | " y: 0.65\\n" 106 | " z: 0.65\\n" 107 | " w: 0.0\\n" 108 | "}\\n" 109 | "color {\\n" 110 | " x: 1.0\\n" 111 | " y: 1.0\\n" 112 | " z: 1.0\\n" 113 | " w: 1.0\\n" 114 | "}\\n" 115 | "outline {\\n" 116 | " x: 0.0\\n" 117 | " y: 0.0\\n" 118 | " z: 0.0\\n" 119 | " w: 1.0\\n" 120 | "}\\n" 121 | "shadow {\\n" 122 | " x: 0.0\\n" 123 | " y: 0.0\\n" 124 | " z: 0.0\\n" 125 | " w: 1.0\\n" 126 | "}\\n" 127 | "leading: 1.0\\n" 128 | "tracking: 0.0\\n" 129 | "pivot: PIVOT_CENTER\\n" 130 | "blend_mode: BLEND_MODE_ALPHA\\n" 131 | "line_break: false\\n" 132 | "text: \\\"Test\\\"\\n" 133 | "font: \\\"/example/example.font\\\"\\n" 134 | "material: \\\"/builtins/fonts/label-df.material\\\"\\n" 135 | "\"\n" 136 | " position {\n" 137 | " x: 0.0\n" 138 | " y: 94.0\n" 139 | " z: 0.0\n" 140 | " }\n" 141 | " rotation {\n" 142 | " x: 0.0\n" 143 | " y: 0.0\n" 144 | " z: 0.0\n" 145 | " w: 1.0\n" 146 | " }\n" 147 | "}\n" 148 | "embedded_components {\n" 149 | " id: \"test2\"\n" 150 | " type: \"label\"\n" 151 | " data: \"size {\\n" 152 | " x: 640.0\\n" 153 | " y: 32.0\\n" 154 | " z: 0.0\\n" 155 | " w: 0.0\\n" 156 | "}\\n" 157 | "scale {\\n" 158 | " x: 0.65\\n" 159 | " y: 0.65\\n" 160 | " z: 0.65\\n" 161 | " w: 0.0\\n" 162 | "}\\n" 163 | "color {\\n" 164 | " x: 1.0\\n" 165 | " y: 1.0\\n" 166 | " z: 1.0\\n" 167 | " w: 1.0\\n" 168 | "}\\n" 169 | "outline {\\n" 170 | " x: 0.0\\n" 171 | " y: 0.0\\n" 172 | " z: 0.0\\n" 173 | " w: 1.0\\n" 174 | "}\\n" 175 | "shadow {\\n" 176 | " x: 0.0\\n" 177 | " y: 0.0\\n" 178 | " z: 0.0\\n" 179 | " w: 1.0\\n" 180 | "}\\n" 181 | "leading: 1.0\\n" 182 | "tracking: 0.0\\n" 183 | "pivot: PIVOT_CENTER\\n" 184 | "blend_mode: BLEND_MODE_ALPHA\\n" 185 | "line_break: false\\n" 186 | "text: \\\"Test\\\"\\n" 187 | "font: \\\"/example/example.font\\\"\\n" 188 | "material: \\\"/builtins/fonts/label-df.material\\\"\\n" 189 | "\"\n" 190 | " position {\n" 191 | " x: 0.0\n" 192 | " y: 4.0\n" 193 | " z: 0.0\n" 194 | " }\n" 195 | " rotation {\n" 196 | " x: 0.0\n" 197 | " y: 0.0\n" 198 | " z: 0.0\n" 199 | " w: 1.0\n" 200 | " }\n" 201 | "}\n" 202 | "" 203 | position { 204 | x: 320.0 205 | y: 480.0 206 | z: 0.0 207 | } 208 | rotation { 209 | x: 0.0 210 | y: 0.0 211 | z: 0.0 212 | w: 1.0 213 | } 214 | scale3 { 215 | x: 1.0 216 | y: 1.0 217 | z: 1.0 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | --------------------------------------------------------------------------------