loco-rails 3.0.2 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/loco/version.rb +1 -1
- data/test/dummy/Rakefile +1 -1
- data/test/dummy/config/application.rb +8 -6
- data/test/dummy/config/boot.rb +1 -2
- data/test/dummy/config/cable.yml +2 -1
- data/test/dummy/config/database.yml +1 -1
- data/test/dummy/config/environment.rb +1 -1
- data/test/dummy/config/environments/development.rb +9 -2
- data/test/dummy/config/environments/production.rb +7 -4
- data/test/dummy/config/environments/test.rb +5 -1
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +6 -3
- data/test/dummy/config/initializers/content_security_policy.rb +25 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +2 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +2 -2
- data/test/dummy/config/storage.yml +34 -0
- data/test/dummy/config.ru +2 -1
- data/test/dummy/log/test.log +126744 -0
- data/test/dummy/node_modules/loco-js/README.md +507 -233
- data/test/dummy/node_modules/loco-js/dist/loco.js +7 -81
- data/test/dummy/node_modules/loco-js/package.json +10 -10
- data/test/dummy/node_modules/loco-js/src/ui/form.coffee +3 -3
- data/test/dummy/node_modules/loco-js/src/ui.js +1 -3
- data/test/dummy/package-lock.json +3 -3
- data/test/dummy/package.json +1 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/-J/-jRuBxSBqhGhMZGMDZgR4DvG1BudHiZGmVBTmz1oAV8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/-M/-MsMotp1C9HgzAn12mZgpqu6KnrVK32Okh6SWF6jvqU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/-k/-KJg9V2B-A1fXa2LXMQin3xECyIalvq2UtqIIyv9inE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/-v/-vAVDXqMwGDq9u9Gbxi1zxzPdNI3TlIUkqXRHeasvwQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/04/045RpZnZJtJv9vtlsFzbsZAwFYs4UQW_9Ns3LyJDV4Q.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/0N/0NVRIIL-ZSSpJ8OQHmga-8AK6x6woreSWoTBLkawA2w.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/0m/0M3-rQxdgDTJWk18qHw4h8Zns3FwakHzy_UjwQYTczM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/0z/0zZT1sgib4AROErauN9rju9earD2VQru8UXC7VbPlfI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/1Y/1YKbjlAZOn64g_S6M5Mz4YWKQGP7rtXdqwalLn-P7eo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/1b/1Bj4EDCR68cTjMTACFnvlZkvyTyKix4at6CVWbhSOAM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/1d/1DDkAMvLObx_gOHZGTeySq9PrBMY3TeqXlPT9xscdYw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/1q/1qAiKgNy9B7x5a0tlQKwDZRpSlBnwAtELBNSu8HxVxQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/20/20EbD48kFwr-zqVSpyWM9wcr9Si4sHsgbfSylSZNhWw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/23/239LB-LO6tGDhLX-pjCAeOz28LxDJBEmWANawq0PdyY.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/29/29NJvpc2kBieKJnYoKCG0BcR_sojrDfi4i2eGlhgaZI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/2U/2UnV7c8HhsA2M33giUkV082VveFjXTq5Lt4CPWjE6nM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/2U/2uAcy30GPO3OQevtkqSWG6Tc371Wq3Rok220OaHJTLg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/2x/2xNgiex3ZhWg_PaJGWpjw7BElUNQV5L5ICQ8D2moc50.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/37/37NhvdBvGZ0mx0MkZHJtREGefAgNVFq9JU36IunN68s.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/3X/3xGHTkguK7X9IPjY3_ZnfS35WMFlLVw-y5bXQPDjjQI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/4T/4Tzip2JxdZ28byZUSitnZ6RgV9k0WVA0z2b-JhzWSnQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/4U/4uWUp6M_r_FwsyJyzSiX8Xpd9K_Nlg5j3BuYXBVmLRk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/4V/4VLSk-lP6PdlgeU1eRRI6a91H281wRx1CxTVIHeeTfI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/4g/4gBCU-WOdGW_TYUF3bqE25rTgi53TtKKImiM7uscQbk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/50/506yt6Cx9A__9g2xCVVwzH3-19832sMypPmrkXDDUv8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/5A/5aBMtHHis9BvHg9ddjXz7nRWIuoTOyA8oSHdd6uC3GQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/5F/5FzpIJEuO74KSEZZ5y3PudAqA-HIegwGXZPAD4S1xNc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/5N/5nC9yg7UHf4e6744uZdp_0MQgExaE6qvveAXaNuxEoM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/68/68KC0go0A2eE-RI-w3ltIMb2DXqONgKJakjzJAIxMBM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/6T/6TpXWEA62rMCgqBpKDDxJ_Gle6Rh01q3Ezbi05gi9CI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/6V/6VIZUqL5vguQjNdfmNG3XjqRvwUH72DfqNNQtHeSFY8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/75/755xzRrV3xie9h2cetIhxoFiVM4-o7SuD3HQxYbC7I0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/7P/7PWBklt7MaryankEJuI_sKqSimWXMHm03BmtB6EEMaE.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/7W/7wPtcZBv7LW1UnGGsVYTkYxG6Dy5VtXmc0_MaDu4Csc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/7s/7sR9YPNjScCTLblQmoTh8Am-ULBGPvLUKClubUR7qnk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/8Y/8YKCtSUBuSLmMojiaSORVEzqRUpHrz-voAMbZeAiGHw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/8h/8H5L4TuXC5_TRbGA9HH4H6t5Ld37MxUVPF5XsSzQFeE.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/9L/9lEzeQHqRIYHrrJMEAKUjtWlxM6E8LkCDq4z7HTiBZc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/9U/9UOTdMvoirr0jEK9j7dpdwkl00LRkRZN_NIvCXsdVkc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/AP/aPMzvSm3b3EYCzcLQQNXq6BkRG68q9bgfAnckB8x4E8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Af/AfX_XFlEXjEPeIctsgN9FeGTcNL-dOWd0f9X_LT1ajI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Af/AfuoOuSnkqyc44-xc9shwCxrcxGF5c8WIgFYQxEILOg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Af/aFbmDFNRBLylnZHmIQ1U6C7PG5WQQBOALHrt7A3r9o0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ax/aXl8hbMuDt-ohaFfr16QKjKDIAkcT3jyLhrqo0M__dQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/BN/bnSJu0O_S8xNZzGCslGmhSQA62dQWspOdDW6s2pTpoU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/BZ/BZFgfdZERw8E3xipNILgbSGbwpzx_veQ3TxmOdy6yk0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Bb/Bb_vnXwR7tiC9hVuc71Eea0iKU2aOhoIXI0V29vJUgk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/C3/c3U8UAGFvV59zB6nOp9C8GUxM7CEICBsSYIoTex-_jE.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/C6/C6MLyXtzDDt7-hgOZLctkCsGUVo_pm04TAb0jfswhsc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CE/CeeSNkXOcaUApA7Ym2L3yCxhISeo2XlGaR6vrqGY1XM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CE/cEI7VTCimg9fatNwZWHtZDmZgf59YqKmwAq9q3804U8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CF/CfY4Uq2u76hDx0HCCogYINX-JerTLRDZq2jlHrGOC0E.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CJ/cJjALcy1FEqSBR0pT-pY2lSfB1youe8rU69yyAFrP_0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CS/CSyjHOBFaJCfkYPE8f86M77zB8CjHpE7B8x2ykgWgBQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CS/csdmOH4wix3KiEqv8Oh8GtCZY_lqb9tklr0uZJb_1ek.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CW/CW947cOZHJKmiyqHk3Ve1NYHBTNCTHiVGle0wgU25_M.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Cg/cguRFQrPdrHGU1tlohvdfzqMGPcAiZ_-Q50uAAmF9iI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/D6/d6DsSUkqQaPOnUoAWI-pg3gtOBpqMHHkGoLVmuVFspc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Da/DA_MmZgCbpy1zDFDMBDYnr47nEGnYj6R53nsglZ09PU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Dm/dM1Vl0sGm6I9wmuijMzobOUbm9oSUC_AthCdDFeixQw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Et/EtD85CZ6VxKK1L_qnDqISc-sLIYQm39iU5bUPNi3tq4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Et/EtS1p-pnppkg9qA3tt_7e9PPEj3FX2Jhy3Pf83CFc6w.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ey/EY80cm6jZKFEjbcqjqxUL9MtOdzDw2nSCjKjmijGFrM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/FL/FLChJccH5-j8e2dNKQEIIFYhaX5S4c9JWJUeUHYOZWQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/FU/FUgqGw-FhbXYUP-B-0fPeRwBA0ha35kn4zKFEnTuK1A.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Fq/fQLHWq_L2Z48GaLGDVmZykCMGeKBE0rb23umkjkzQl0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/G7/G7YLP2UAQr--j8JCZO_6CoFmlUahnmQaNlU9h2x49WE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/GF/GfMP1Y3Q073Gt3dqPuPnqnDHWgvzRpQtJE2yObpZsCg.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/GG/GGaFgGolUFjdoZ0SYuINWV_Ae2DeNvyzjb3BR1hnmrA.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/H0/H0X80RjOhcm3jkRkdV21CMFV6Y82V2vccKGUh8f97MU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/H0/h0iMeYhnYtpI8bcbEobJf-qUOFEtHKNZNTOgVIuA05E.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/HH/hHisN1kDFWs3r0j-FeF9wQK7tHrinMPPq0Dbe1ZgmnU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Hf/HfkmM5cNyrIdFidR1ojxaqZhhJpxF2NqnrAPFaTvAFQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/IX/IxpeBqoQzi5camxHq8KS2gGqUgREWFEN4GOOOmpHHes.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/JZ/jzc8n1ET7GboyrJ_ODQgZjEV5ipU45DcnIxr2_g_oiw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ja/JAuEW_d7r46Jqgl2j83mkwPlAKVe5ShJj7HrAQtW1L0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/K8/k892bs-7cCfnsLPzMB2cPso1drABTLbAdQx_iLv6bzw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/KD/KDa51POY98B5sKAk92udWNqR-IHhG_0-E9HxHwjbfFI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/KD/Kdt95At0dE9pZNPWNiHW8hbrrtFWqCRhZiaPvzs9jsY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/L3/L3FyS-Bz04GuYdSx7feiytzc73GpNlIaisK5U4MLOf4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Li/lik94_AD9SyjPuHst1WRMG3YRfJkj3_VlGZ0_ARNeNw.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ME/me37qToAWzne5ncSpjd4_TNrtDCpCOzDC6-unjUhn98.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Mq/mQSJTZMI_eKnPNzAIps4uHsDjNv6ZsxdoM8ABZbZXm4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/N1/n14mpJbHBbJ2u9SQqfnrAr8E8vq8Gdd-kN5JAmw_OBo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ND/Ndy20UbqG_cF22IVkX3HeTYThx5gtSuE90MIPkqCX6w.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/NS/NSmqVnbwLF-Mc2U7C_tlEAjk-Myy1e109DU2N9zSMng.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Na/NAG2TuJ2p5K3RF-PArkQqxCdrL03bQhGg-UcnwFn-5E.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Nl/NleVcx-nLD5jfgZ3Pbo6IdHvjsGt4o0saCjhN45_Ejs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Nl/nLH4hFiTI1HeA8jDp2-jvWW29SfMpLpVlaRemVkYrI0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Nu/nuuH1I2JoKAz4QgElRyLVoji6ZEKgE0XIILs-KdgQdc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/O2/o2BunY_A1Yxz7jaJYIC8-UTRfFOGWrDOqTgxrfzKANo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/O3/O3wo4xsN2r6dWvB6wvuG9L80esYw-jn-jWwFgGy1k-w.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/O5/o58vAeoySyWuEset-5sVohUgH1QQ1fO0EvwAwtN8yUA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/OA/OAI7EmabRCgN6JLl3t9rTR7bNdCi2fs3i3v6HWEaFFE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/OC/oCBbBHeeLhvFU1TMX4sxiJm1QaK4FyhCIX9CIOCwE9s.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/OS/OsfMqShZ5GozwHLyoWf0JirP4nFDNhKaxTRwfy2vMlA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/OT/OT6Sj1TCATUCAZ0Q-xXL0sn0NpnntNQ9Gy9XwOd80UY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/QA/qAn_2k55usGtjS89n7bbCfGpwr209bH52tsd2em0TJc.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/QI/qIRh24J9ocyHsA6i3IaO4u7a9aqMAjBdZ3CvbC7wGOo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/QN/QnRACKQ7yeYauWhRNFW8tOBvKMyAJFqhp_Ays9h20ek.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Qr/qRpUmYXiJEYpCCJvkhSfD0dJz5YXczQ2EZU8bHSDiqI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/R3/r3eYTIon6wkDuStPJrBGz5AvHkVk5oLStbQD5LFNW_8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/R4/r44RUOYmRkX0TnidifKV4uFEx62D9Jg1qr0ySL8m4XM.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/RH/rHzwnhmhiiSZY8sOeEwncKuLVB1_gbyYCCE6le7LMg8.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/S4/S4owiRAgNfA15vBugDPGn3UsNILiKJz9zwHIumH6VcY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Se/SEBe8cS9qNeqNsjUHHUFvLDXcHxgzjLlXWqDdqu8lGI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Sj/SjNOl6b-OfSqaGMhBV4wJm48DnyO2QLI26Ll_1yhwLU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Sk/sKXYmTeqpSxkL7uUn9T75lNSAoER1-5UsdaRyh2Ae9c.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Sk/skmDYXO98axQLERsO2_euRDt1L6TnaPnx4aHU_VRxcM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/T5/t566-PEV6mlZCVubTzRPyFjOssZR725Iin4AEXRlbKo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Tb/Tbmaaa2obwjsAEecNSsXx1KJn30e6LncEFpug9V6RAA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ts/tSHFV8C7on481FBnZJelmA6okEk6lNj92G1qm_nKvsU.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Tu/tusRYqxMqyahXyA-VelHkt85rJqXZzVq-PlwWVBreTs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/UA/UAl-hGuzv_dz8hycNQIIm-Of8HLSNZ869-XIw49WSn0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Uj/uJhXVnOcGEXTag9G_u1m5q62UfEl8FFQW01UaQrq0X0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/VC/VCa4MztoUr9e7ig5JhoHNE-r_FDRjIhUc8Z8JB0PyJc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/VG/vGkwD4OSan18niAi74mr9fIfhUMo-CcvaBx74YdEQd0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/VQ/vQZLZuNs0rfy_42UpBaOJtleUiv_bWzHpATDKq7bbQw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Va/vAwij3yp0Fm-1sMkWFd6bUgQ_jM9egl1RSX3pOCd3a4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Vd/vdOhlhDTV_4Uv11YmG1lvRc0vCuVm4uKaFqq6becZw0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/W5/w5ukVExl2Gbi1RlBdqWDI0fq2iBbtjAH7mMe23pK92E.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/WJ/wJqyr3oYLZYPoGuRJCknJVApbEQObRm3LYYjBC2NqAM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Wg/wgn3qoQdml6N8XDer1Zlq-t473T8Ub-g6utMjIT9FB4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Wh/WhWmF31-n-FhKPKH8KNjppS_8AWIzMbwu4CxEjckkx8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Wv/wv7UvPiWmxoBUkwcSE7sbZw2O7h0CX5Sk5qR7_MDo34.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/YO/YoxFJ0rIjkG7FP4SCq-uTONRO9gZRgwEeRoCeV_l6A0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/YS/Ysbu_r9GBjN6MiA8P1nX0291K9qWQluHyUeuhWmeuss.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Yr/yRP9b103fDZixn-eWMJUTXvQv8bzW32uBYfnCkkb_2w.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Z6/z69lPas07XA2Vt1tcPWrdyzjV_ZYsa_shDGrw78eOts.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZH/zhZl2ymB6N3iwcQ9qKlprF2pIjdLsj-BhfzE9GlXqgA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZL/ZlDOpYG33TBzlaIR5yQTZ-J1gvllIU34U0qNTbKBVm4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZL/zL4l2qqHDbzP0xBWi98Pdax-R3ZzYh00Xhd0XJRZiHE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Za/ZA_14735hKZvWBgr9jKULLIQ77QK9fl5wwUpe6ddxw4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Za/zAKnHoLawciLm457YLz02FgHqpjEAuvEjFInlExdP9Y.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Zi/zilSeJ-LxWIVQfRhTI8DoSLJRYSm15-tahLja_zNH-4.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Zj/ZjNt6Wn3GUUmkNzKBS1ZUwZIdDualU-dHmmEgzzqhvA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/_6/_6kZ5T2IKeSJ8MICFu1E--QKGBDL226cMA4XyD5p_7M.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/_7/_78lkXIsJEffzvxHikyxRSABDq7vkVtuO0PRu_zf0Uk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/_T/_tK53AXbXjuvR3Wyoo--yrqIkqsySwpa1utx6H9O2Zo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/_X/_xOdrlbtAzE_PoR-gySvp5dHLtDNJTXX-GNPzz6jPwg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/_b/_B2gIo3CjO8JsonizRTzG-zd-XTQAPSwXM5SFs-_xH8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/_r/_r29Mrm2koFgy-JBl1pWxF7BCdvw8i1T8sMaB4Q8ZS4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/aC/ActeN9-QxVesaH9n9XqNxvpZHlUROHXafrENFT4u48M.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/aH/aH8rFI5lbbuH1SCnsFpxppYeaTPVNC86AI4klO5eSWY.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/aJ/AjPOH6_qloJ7aDxoPNHPjk6dNZTHt-OiH4tlnIc5cB0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/aY/AyW7YgyCLSB154k1tlcoAOTlufIBNW2UocPiCWa_yy4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/bD/BDKpFuQVYcZahDBQMAD7ttmBPYq0MHmoZMIfBeznnHg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/bK/BKKOtOfY7xbwY8vxgPbTeCM-ilm4Mhyfbjc5QqEfOBg.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/be/bErZVKsZiF62FvmVXFk4OwyKZjcJrXWUkx2qAODwvMU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/bf/BfVfHDyb4e6-DnGwOnCX2e51PnJRg7HzSx9HLOXzhs0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/bh/BHZjn58nVz4e7103hCj3oh_575HxBVfdUj4sHNo2qxc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/c_/C_YE-FL11W9ba7f_Iz7yvsn52Jhdb7eaTYGvVIIxBHk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/cd/cdL_5UoQCgl0Ah5ZUkrf9BGDDSwD4V-jcWKPEH-7UJE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/cd/cdW7T2xOjMwS8uWkszfaGZqZE8FdIiO8yoHbMpiHUaE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/d1/d1tZv2ebo68ZUUIBz85k3Vfx_sW9q4IdTV05-st8QfU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/d5/D5O80Gi2oT3uZSFpSVMCqzIjR9y3NhnOmkYzpoIIcHE.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/dB/db3DRa6W4FbcpiO3nwEml10a1N7M9HCYdERbGBnxjO8.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/dy/DYxlSaGCG-CgIG7P87BxXWLOAFvb658rPRRYZnpzhZ8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/dy/DyMpjNQjzt1a__XV8R0nKIIp93-0s6s4EOBQdZy2KME.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/dz/dz8AQVAIIMLcUhT4eFPxbPwOOXYW20-dZcbIHtAzgzQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/e6/E63DnYlU80qBrNwmuH6kMekVut1v43fn991A353I7Hs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/eM/emEn10GbCIoovMonR38OCWWUZzzCXyoqrTHrY8mIn-M.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/eZ/eZXWd6Y6QizrZHT3B0KbsPs8UFIRRmmyyI3ZMfuTQTk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ea/EaF5hKpf4SxL_yA_MHGUmc1D5mn8muYntlhum5KEmoM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/en/EnCL_IleDp9dMO1q1ao6S7fiDRgmUZJ8Y4zXyA9HYIc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/en/EnR_QHTqDyi16u2ZmDsP31jSqzjDY4xl6OxdyfpaPS4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ew/EWYjDQCTL2L5WCraRujd4TRHLSkvkpyqtJzHSzVrMD4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/f-/f-UqXzWYSbZ-CIQY1IzimMDwJv1LPTA_BfvB9NET0NI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/f3/f3aQK52Ym39aOB2Lq19c6_aNViY3mbLnnXIFsvDaDUQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/fR/FrrHVmRkviiP4uwkJPKz4Y86xuQq_osOK0Qgrh0lpFo.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/fe/feu-PRRDD8LepR7mof4Xr9YwY6tpbMRghBTytncQC0Q.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/fm/fMy0aLpsClmuO7hUcn1KLCcr19XztZ9fZz58XQ3nUns.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/g-/g-wAbQD53qGYu8hZLVaygiiohenz3qjJinHAxiMf4Sw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/g0/g0imhOexk0aezqfjK7gXIElBhmHFwmGSnRdnMpY02rk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/gQ/gqlB5sygBkcCKWPT_m045GXikr3LdsNKQTK38HzdR9E.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/gV/gvwTSNs91TS6yxuXroY5gBZG0pYjZnL0gag3Lv6VkgE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/gh/ghV8j2im5GvZeBtG3wHHCZxkXSoy06Tmbwi5lEtYwC4.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/h3/h3ClhnKoI5GsYVMoyZUWXUYW2wl1qyGWcrLO-uJoWfA.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ha/Hamm70ci2PlZfFvVFpB5Gg2G6RxSB-u_n5bYXoMe8Tw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ha/hAFkNngWOCLp6flSMn8im7GFOp-BAnRRuXlFVXq333s.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/hy/Hyp1y4ptB6As-dBENHcdiSc6fJMsQctP1twuSXl72qc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/i0/i0D2lY1FRDLs05Muw5ycE-YZZvDQIzOnPoU5Ni9aQcI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/i3/I3z12f15y9WDg7gY3Rt6m-qrRGBJPJH03ulKntjFDNQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/i3/i3OTzbDCLJ8pTGCjkhGzQOXqo2GPRmkCw9jk04WM9W0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/i7/i71w7jiqj0J6zOAknlSYesSXwUNcgOb7wqGMtDuAXGk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ig/iG3baB4ZrLao8WqfgyARQ8Tqb9Ia9D6ORZWV9piUeqw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/jI/jiBd93PekB8DrxFub8xW9NmoPMMeayM_qcWRJWIfXTQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/je/JENZcQ82H4_sXd8Ro0o6WRktEPbeHtSwEHdZ9l30SOk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/jl/jlRgXxxizzc_saFGp3PJQUqblfsPlfFoPIKrniW3UZk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/jt/JTq_kXXBxhVpKp0YWihY_uBqRN1DjBnxRBpp0iTz-sg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/kH/kH9itDMo2E-CQGRvWA6iwOx8vWTjL-FtMgnl_s1TvgE.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/kH/khFXPOgsfIU-2_MUEyvvaBgfzpIqqo3vmu5mRTOhQNI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/kP/kPbrphXtXLC4PBqBKaX6xwRL0-5x9bekJYJbSAIX-lQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/kk/KK8uDCIlqJQZhXxBrWfiEgG8FTKUrCJzS4Yb0_0TrOE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/lU/lUaihZsgYT2d3JO_poeFQmfe3oWBewpu0KLTLa3a_uM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/lg/lghwJp6Z8DJMifhru2D1R20qf3DusCl6I5o70w4GcH0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ll/llWi7_A77KHN1gKpVbNR0WbrrLVA5SQe-iidipQdEV0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/lm/LmZck0y9Vz1NrTi5oqDqr27yMAGDFKycntHi6GLdOWs.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/lo/LoOEy7WY0wVMaXt-dQ0uy45w2GJruD4b0fFrdO9CN6I.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/lq/lQqsDUhE1r0m2x9rSPskVxh5rAsVUlul9r3fzMn6bH4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/lv/LvrHX55tDahcDMVaFFC_qOr4uPjYy_bgKo0jnEsqaK4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/m0/M0AZbK-CWbV3dYvCjPeLy90oM16NM15bQhufFgev3HM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/m5/m5R0ZONXVCJUQmzgoqLCI7RaUp5LYGWlvegRpDNS-XQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/m7/M7appVnIFuI-ZCkP3CGJDB0J6k2cDAXBVACdc43r6X8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/mK/MKhF3FijReaEzG7pGqah9bNsOONO7Th2rSAHS9bJ4ZM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/mP/mP6LBa79RCTTxM1BolHC8La-aWx9aW2wKksWmj4vHMg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/mc/MCI94MLeSLN1B28T86lUUXiWtm6Q773y7EsNQfBnD1c.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/mf/MF5GQ0BtToVWzvh2WHYb6h_HcCV5JN5tw1Dm9-5cCvE.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/n0/N071PNk28aG6cjn-C9cYuta85IIl7QoiY-GewjsiFpI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/n6/n6oCazgG4IV4elcWQMkZjh6r46xwC5DYjO1aTAZZDU8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/o0/O0i0iIv7zGPeOb_-jN7Ryn34QM5utq7vM81lkaA_ilA.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/oZ/oz-sfwWLbMDBXL7IwpojK1OehOsJkfT5KmOMpks_iks.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/oj/ojgmMZhTYidA15m1oZ8CwJuGPpfntMnGEIGNA8cNq5I.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/p6/P6IAdOr9DmJf9DgtEUkIB0Bs1KD3C4Sypwfk4akn0tk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/pY/PySfrJS4Cuvrn_ahoCqM3vWAyzMnF_K-DlWXSbT11MQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/pd/Pda1-WMjhTjtFxkBJjKPFMcfdpBhG7tR-xVbo3mWdMc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/pg/PGJ2D-e6Ocnk9_WMGmwSMox07vayNVdIsiloF5d8GpM.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/pm/pM67czplwdAZzOk3x1FXfAD-HzW_60_Z02xc18BQNPU.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/qC/QCMhxuJ_q0gnVwyfEkYxLLSBjqb7cKPsmKSptM5EDe0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/qE/QetzHFbCWN84CprFPwJKzBfdnGOzTXKqzsq6KF94GJo.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/qZ/QzXl6uc2hVLL_YBCUfsprmgJ7gK4TguqnNAilxl3QFI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/qx/qxuO9FAiMXCdUzynMt-oySHqKgr1z6dtFaj_LoR31o8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/rU/RUI34u5OG8YGAgQ0qSfO5-9QgcViZEZC2MDgDTi563Y.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/r_/R_kf8JEA1gVUI_sYnXT8d--JVrXcPypMkUiYxw6DCZI.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/rj/RjBQJniH-xp64SK5zBIC_6wCF_R5-xfIKJiC_At-gfo.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/rz/rzwcZzNQxT-kIJHRyu2ka4RHfQYMteLOWU6LvQGruLc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/sd/sdu_LnFFspFc1eIGDCM-kbkHJq6NoAWS3gCRjbwMlXg.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/sm/SMUWkrp4Al4k53zXyX5Z7B9QClPcd_sW0GicK6Eb9QU.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/sz/sZceTKJ8koS1NE-wfhiV9uGnQ8o76g_badaXButD7k4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/t-/t-E6fbYdF5OXStzPu6ikUiH6gafLehi5svGyVij9mDA.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/tf/tFvhOwl2Rg8mFyvxdG44VfyLEeg_xmsezuLcc7hA7Is.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/tm/tmO60-6rd2wuBnZhSDKmdbIMSEvhrGRZABHHxglyg_0.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/tv/TvIYS_jAwwxV667TXI8VBiHOQiF7BJZ-bYFUXd5xSm4.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/u5/u5uT7ESwnB72MosoxfUmsQbvT_PrXrnfC1xZqqsk8x4.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/u9/U9EfIWEjgFaFZxCja0i3LUo7AR5wOuc6CGgeIlH1vjo.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/uD/UDG7a_i2uwJdRN3qbg8GOBWvXEyZPJ18z1wL6NMi6RU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/uS/US2saNgxNzkqQHPRZdNTpVqaOSeV-qfKHUTjyvcgFdA.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/uU/uuH4OCO47rfZ_ynjGG5XIwo9pJ8p61iVm8E4oBNICrM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/uZ/uZwUbrEKzsqHvDzJsJQ5hyN6UXQljX_YwEkm4zqmoWk.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/uf/UfMnCTlLlVi_DSUuzI-raYDV7XFu-wwPptc7Gx7R5oM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/uh/uH079nnrp7Apb59iUZQNHpsOfih9BJivKMoO48ALit0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/v-/V-ETmls9uJZK-_2JA9ERZygrRou3PR1Hk8prOb2-aMs.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/vF/vfQRdcE4PZlXuUk2SmBzygcSI3RN4fnhTFBpVMgv3PY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/vm/vmIWzEngzYnOh3FQCZspQYgJb_02thLy3aSdwIqpdrM.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/vp/vpOj41A0lZr1AXXbqRHqV-VNMoTipWWXgPI0xxY7Asc.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/wW/WWxa1pKji5boHoYejj6C4086ziHFwjbQ5nbDjps_GME.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/wu/WUxtPZkwXA5k_GkLQV6Mi4gvhaaXdpvQHNgal0J8imU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/x7/x7PYh8DJvPykcEqpVab2vcY9-GFz-3cqtoMlRAu94Uc.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/xD/xdMJVhl6-lho-dXe9d2EWtkeY8z-qwFr1WLb0X1Tb7A.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/xE/XEIcOoWba_PjXAIVTFQ2Hp8DP5XA6fWN12kpDOKpc5c.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/xH/xHwTBYA453ITOilaM6LNpajRbW9tKk7S6oS0muuzBrY.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/xn/XnIdG5NCy8rWkzrRxYLbgKzNlzDdYQGz9fQpwgmoUYA.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/xv/xVkljJuUUQCpukAdsOefDDpz8W7RQyFBKMlxBgB0EZw.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/y1/y1C9IvfyR_xFDN5PjrmYTwyYTfbA9idTuFco8ECyLM8.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/yK/ykJm5VdQ64JMnAeAiTtIu-rMDHUeK_wnUadLqypvXws.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/yZ/yzty8n9RPg4GNN-msWr1ErUYEvYxCUrWMzMhG0qO0E8.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/yd/ydGsXvJHLi1amXlTZU8Q4P0E2PmEJEkGvdYVXXDf568.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/zO/zoGQwZ6FUpfH7981PVWSV8NZ6-ZjLz5H50iZwyFdbRA.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/zk/ZkfsIEQeLV_xhLwALIWPSCmEjQU3sDbzGaFuSF0G3hY.cache +1 -0
- metadata +529 -25
- data/test/dummy/config/initializers/session_store.rb +0 -3
- data/test/dummy/config/secrets.yml +0 -22
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/production.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/node_modules/loco-js/src/ui/tabs.coffee +0 -24
@@ -2,292 +2,584 @@
|
|
2
2
|
|
3
3
|
# 🚧 This documentation is under construction. Come back soon! 🚧
|
4
4
|
|
5
|
-
#
|
5
|
+
# 🧐 What is Loco-JS?
|
6
6
|
|
7
|
-
**Loco** is a framework
|
7
|
+
**Loco-JS** is a front-end framework similar to recently released [Stimulus](https://stimulusjs.org) in a fact that it doesn't want to take over your entire front-end.
|
8
|
+
The difference is that **Loco-JS** was originally designed in 2016 and it works in more generic fashion. **Loco-JS** teams up well with tools like [React](https://reactjs.org) or [Vue](https://reactjs.org) for crafting a view layer.
|
8
9
|
|
9
|
-
|
10
|
-
* **Loco-JS** - a front-end part
|
10
|
+
Architecturally - Loco-JS is a front-end part of [**Loco-Rails**](http://github.com/locoframework/loco-rails), which can be used separately (with limited functionality).
|
11
11
|
|
12
|
-
Loco-
|
12
|
+
And **Loco-Rails** is a back-end part of the whole [**Loco**](http://github.com/locoframework) framework and it requires **Loco-JS** to work.
|
13
13
|
|
14
|
-
|
14
|
+
**Loco-Rails** is just a concept that simplifies communication between front-end and back-end code. You can implement it in other languages or frameworks as well.
|
15
|
+
I am a Rails programmer that's why I created **Loco** for **Rails**.
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
### 1.5
|
17
|
+
This is how it can be visualized:
|
19
18
|
|
20
|
-
|
19
|
+
```
|
20
|
+
Loco Framework
|
21
|
+
|
|
22
|
+
|--- Loco-Rails (back-end part)
|
23
|
+
|
|
24
|
+
|--- Loco-JS (front-end part / can be used separately)
|
25
|
+
|
|
26
|
+
|--- Loco-JS-Model (model part / can be used separately)
|
27
|
+
|
|
28
|
+
|--- other parts of Loco-JS
|
29
|
+
```
|
21
30
|
|
22
|
-
|
31
|
+
Following sections contain more detailed description of its internals and API.
|
23
32
|
|
24
|
-
|
33
|
+
# ⛑ But how is Loco supposed to help?
|
25
34
|
|
26
|
-
|
35
|
+
* by providing logical structure for JavaScript code. You exactly know where to start, when looking for JavaScript code that runs current page (**Loco-JS**)
|
36
|
+
* you have models that protect from sending invalid data to API endpoints. They also facilitate fetching objects of given type from the server ([**Loco-JS-Model**](https://github.com/locoframework/loco-js-model/))
|
37
|
+
* you can easily assign a model to the form what will enrich it with fields' validation (**Loco-JS**)
|
38
|
+
* you can connect models with controllers and views, so they will be notified about every change made to a given model on the server side. This change is going to be emitted as a signal to the front-end code. And signal is just a fancy name for JS object (**Loco**)
|
39
|
+
* allows you to send messages over WebSockets in both directions with just a one line of code on each side (**Loco**)
|
40
|
+
* respects permissions (you can send messages only to specified, signed in on the server, models _e.g. given admin or user_) (**Loco**)
|
41
|
+
* solves other common problems
|
27
42
|
|
28
|
-
|
43
|
+
# 🦕 Origins
|
29
44
|
|
30
|
-
|
45
|
+
**Loco** framework was created back in 2016. The main reason for it was a need to make my life easier as a full-stack developer.
|
46
|
+
I was using [Coffeescript](http://coffeescript.org) on the front-end back then and [Ruby on Rails](http://rubyonrails.org) on the back-end.
|
31
47
|
|
32
|
-
|
48
|
+
I still use **Rails** but my front-end toolbox has changed a bit. Now I work with modern goodies such as **ES6**, [Webpack](https://webpack.js.org), [Babel](https://babeljs.io), [React](https://reactjs.org), [Redux](https://redux.js.org)... and **Loco-JS** obviously :)
|
33
49
|
|
34
|
-
|
35
|
-
2. Run `bundle install`.
|
36
|
-
3. Add `//= require loco-rails` to your JavaScript manifest file (usually at `app/assets/javascripts/application.js`).
|
50
|
+
**Loco-Rails** enriches Ruby on Rails. It's a functionality layer that works on top of Rails to simplify communication between front-end na back-end code. It is a concept that utilizes good parts of Rails to make this communication straightforward.
|
37
51
|
|
38
|
-
|
52
|
+
But **Loco-JS** can be used standalone to give a structure to a JavaScript code, for example.
|
53
|
+
[**Loco-JS-Model**](https://github.com/locoframework/loco-js-model/) can be used without Rails as well and in cooperation with other modern tools such as React and Redux. You have to follow only a few rules of formatting JSON responses from the server.
|
39
54
|
|
40
|
-
|
41
|
-
$ npm install --save loco-js
|
42
|
-
```
|
55
|
+
# 🔬 Tech stack of Loco-JS
|
43
56
|
|
44
|
-
|
57
|
+
The Origins explain why some parts of **Loco-JS** are still written in CoffeeScript. It shouldn't worry you though unless you want to contribute.
|
45
58
|
|
46
|
-
|
47
|
-
|
48
|
-
# set to your Turbolinks version if you have enabled Turbolinks
|
49
|
-
turbolinks: 5 # false by default
|
59
|
+
What's more important is that all Loco-JS' modules are transpiled and bundled using modern tools such as **Babel** and **Webpack** accordingly. Loco-JS works well as a part of modern JavaScript ecosystem alongside libraries such as React.
|
60
|
+
In the future, while adding features, all modules will be rewritten to Javascript.
|
50
61
|
|
51
|
-
|
52
|
-
notifications:
|
53
|
-
enable: true # false by default
|
54
|
-
#pollingTime: 3000 # 3000 ms by default
|
62
|
+
# 🤝 Dependencies
|
55
63
|
|
56
|
-
|
57
|
-
#log: true # false by default
|
64
|
+
🎊 Loco-JS has no external dependencies. 🎉
|
58
65
|
|
59
|
-
|
66
|
+
It depends only on Loco-JS-Model which is an internal part of Loco-JS but can be used separately as well.
|
67
|
+
Although, [class properties transform](https://babeljs.io/docs/plugins/transform-class-properties/) Babel plugin may be helpful to support static class properties, which are useful in defining models.
|
68
|
+
Additionally, if you want to use Loco-JS with Loco-Rails and send or receive signals / messages over WebSocket connection, you have to pair up Loco-JS with [Action Cable](https://www.npmjs.com/package/actioncable).
|
60
69
|
|
61
|
-
|
62
|
-
#location: 'notification-center' # 'notification-center' by default
|
70
|
+
# 📥 Installation
|
63
71
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
#size: 100 # 100 by default
|
68
|
-
|
69
|
-
# after this time your current namespace controller / controller instance method
|
70
|
-
# disconnectedForTooLong: will be called with the 'time since disconnection' passed as an argument
|
71
|
-
#allowedDisconnectionTime: 10 # 10 by default [sec]
|
72
|
-
#locale: 'en' # 'en' by default
|
72
|
+
```bash
|
73
|
+
$ npm install --save loco-js
|
74
|
+
```
|
73
75
|
|
74
|
-
|
75
|
-
#protocolWithHost: 'https://example.com'
|
76
|
+
If you want to use Loco-JS by a script tag, without the module bundler, it's exposed as an `App` global variable.
|
76
77
|
|
77
|
-
|
78
|
-
# at this time Loco's instance is initialized and you can use it to change behaviour of your browser app
|
79
|
-
# e.g. polling interval -> App.Env.loco.getWire().setPollingTime <time>
|
80
|
-
#postInit: ->
|
78
|
+
# 🎬 Initialization
|
81
79
|
|
82
|
-
|
80
|
+
```javascript
|
81
|
+
import { Loco } from "loco-js";
|
82
|
+
|
83
|
+
const loco = new Loco({
|
84
|
+
// set to your Turbolinks version if you use Loco-JS with Loco-Rails
|
85
|
+
// and have enabled Turbolinks
|
86
|
+
turbolinks: false, // false by default
|
87
|
+
|
88
|
+
// the browser's app will start to receive signals / notifications from
|
89
|
+
// the server either via WebSockets or AJAX polling (if WebSocket connection
|
90
|
+
// can't be established). Loco-JS can even switch between WebSockets and AJAX
|
91
|
+
// polling depending on the momentary availability. This works if you use
|
92
|
+
// Loco-JS with Loco-Rails.
|
93
|
+
notifications: {
|
94
|
+
enable: true, // false by default
|
95
|
+
//pollingTime: 3000, // 3000 ms by default (for AJAX polling)
|
96
|
+
|
97
|
+
// display upcoming notifications in browser's console e.g. for debugging
|
98
|
+
//log: true, // false by default
|
99
|
+
|
100
|
+
//ssl: false, // your current protocol by default
|
101
|
+
|
102
|
+
// location must be the same as where you mounted Loco-Rails in routes.rb
|
103
|
+
//location: "notification-center", // 'notification-center' by default
|
104
|
+
|
105
|
+
// max number of notifications fetched at once via ajax pooling
|
106
|
+
// must be the same as notifications_size defined in initializers/loco.rb
|
107
|
+
// next batch of notifications will be fetched immediately after
|
108
|
+
// max size is reached
|
109
|
+
//size: 100, // 100 by default
|
110
|
+
|
111
|
+
// after specified time your current (namespace) controller instance method
|
112
|
+
// disconnectedForTooLong will be called with the "time since disconnection"
|
113
|
+
// passed as an argument
|
114
|
+
//allowedDisconnectionTime: 10 // 10 by default [sec]
|
115
|
+
},
|
116
|
+
|
117
|
+
//locale: "en", // "en" by default
|
118
|
+
|
119
|
+
// if provided - Loco-JS will be using absolute path
|
120
|
+
// instead of site-root-relative path in all xhr requests
|
121
|
+
//protocolWithHost: "https://example.com",
|
122
|
+
|
123
|
+
// this method is called at the end, after given controller's
|
124
|
+
// method has been called. At this moment Loco's instance is initialized
|
125
|
+
// and you can use it to change some settings of the browser's app
|
126
|
+
// e.g. polling interval -> Env.loco.getWire().setPollingTime(<time>);
|
127
|
+
postInit: () => {}
|
128
|
+
});
|
129
|
+
|
130
|
+
loco.init();
|
83
131
|
```
|
84
132
|
|
85
|
-
|
133
|
+
# 👷🏻♂️ How does it work?
|
86
134
|
|
87
|
-
After
|
135
|
+
After document is loaded, Loco-JS' instance checks following `<body>`'s data attributes:
|
88
136
|
|
89
137
|
* data-namespace
|
90
138
|
* data-controller
|
91
139
|
* data-action
|
92
140
|
|
93
|
-
Then, based on their values, it initializes given
|
141
|
+
Then, based on their values, it initializes given controllers and calls given methods. Example:
|
94
142
|
|
95
143
|
```html
|
96
144
|
<body data-namespace="Main" data-controller="Pages" data-action="index">
|
97
145
|
</body>
|
98
146
|
```
|
99
147
|
|
100
|
-
Loco-JS will act like this:
|
148
|
+
Loco-JS will act like this (simplified version):
|
149
|
+
|
150
|
+
```javascript
|
151
|
+
import { Controllers } from "loco-js";
|
101
152
|
|
102
|
-
|
103
|
-
namespaceController
|
104
|
-
namespaceController.initialize()
|
153
|
+
namespaceController = new Controllers.Main;
|
154
|
+
namespaceController.initialize();
|
105
155
|
|
106
|
-
controller = new
|
107
|
-
controller.initialize()
|
108
|
-
controller.index()
|
156
|
+
controller = new Controllers.Main.Pages;
|
157
|
+
controller.initialize();
|
158
|
+
controller.index();
|
109
159
|
```
|
110
160
|
|
111
|
-
|
161
|
+
What's important is that Loco-JS looks not only for instance methods but static ones as well. If some controller is not defined, Loco-JS skips it. The same situation is with methods. You don't have to create controllers for every page that you have too. You can use Loco-JS only on desired ones. It does not want to take over your front-end. Augment with JavaScript only those pages that you want instead.
|
112
162
|
|
113
|
-
If
|
163
|
+
If namespace controller is not defined, Loco-JS will assume `Controllers.Pages` as a controller.
|
114
164
|
|
115
|
-
|
165
|
+
If you use Loco-JS along with Loco-Rails - after calling specified methods, Loco-JS will try to establish WebSocket connection with the server and will be waiting for signals / notifications.
|
166
|
+
If WebSocket connection can't be established, Loco-JS will start periodically checking for new notifications via AJAX polling.
|
116
167
|
|
117
|
-
|
168
|
+
# 🔩 Merging classes
|
169
|
+
|
170
|
+
As you can see in the previous section, Loco-JS must have an access to all defined controllers to initialize them and to call given methods on them. Therefore, they have to be merged with `Controllers` object which Loco-JS exports.
|
118
171
|
|
119
172
|
```javascript
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
173
|
+
// javascripts/index.js (entry point)
|
174
|
+
|
175
|
+
import { Controllers } from "loco-js";
|
176
|
+
|
177
|
+
import Admin from "./controllers/admin"; // namespace controller
|
178
|
+
import User from "./controllers/user"; // namespace controller
|
179
|
+
|
180
|
+
Object.assign(Controllers, {
|
181
|
+
Admin,
|
182
|
+
User
|
183
|
+
});
|
184
|
+
```
|
185
|
+
|
186
|
+
```javascript
|
187
|
+
// javascripts/controllers/admin.js (namespace controller)
|
188
|
+
|
189
|
+
import { Controllers } from "loco-js";
|
190
|
+
|
191
|
+
import Coupons from "./admin/coupons"; // Coupons controller
|
192
|
+
import Plans from "./admin/plans"; // Plans controller
|
193
|
+
|
194
|
+
class Admin extends Controllers.Base {}
|
195
|
+
|
196
|
+
Object.assign(Admin, {
|
197
|
+
Coupons,
|
198
|
+
Plans
|
199
|
+
});
|
200
|
+
|
201
|
+
export default Admin;
|
202
|
+
```
|
203
|
+
|
204
|
+
You don't have to define namespace controllers. You can merge controllers directly with exported `Controllers` object.
|
205
|
+
|
206
|
+
Remember to polyfill `Object.assign` or assign controllers using a different method.
|
207
|
+
|
208
|
+
Loco-JS exports also, among others, the `Models` object. Remember to do the same with all defined models - merge them with this object.
|
209
|
+
|
210
|
+
# 🏛 Structure
|
211
|
+
|
212
|
+
Loco-JS exports following structure:
|
213
|
+
|
214
|
+
```javascript
|
215
|
+
export {
|
216
|
+
Channels, // object - since ver. 1.3
|
217
|
+
Controllers, // object
|
218
|
+
Deps, // object
|
219
|
+
Env, // object
|
220
|
+
Helpers, // object
|
221
|
+
I18n, // object
|
222
|
+
Line, // function (class) - since ver. 1.3
|
223
|
+
Loco, // function (class)
|
224
|
+
Mix, // function (mixin class)
|
225
|
+
Mixins, // object
|
226
|
+
Models, // object
|
227
|
+
Presenters, // object
|
228
|
+
Services, // object
|
229
|
+
UI, // object
|
230
|
+
Utils, // object
|
231
|
+
Validators, // object
|
232
|
+
Views, // object
|
233
|
+
Wire // function (class)
|
234
|
+
};
|
141
235
|
```
|
142
236
|
|
143
|
-
|
144
|
-
|
145
|
-
* **Channels** -
|
146
|
-
* **Controllers** -
|
147
|
-
* **
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
*
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
* **
|
237
|
+
Brief explanation of each element:
|
238
|
+
|
239
|
+
* **Channels** - the namespace where `ActionCable`'s subscriptions are created
|
240
|
+
* **Controllers** - the object that you have to merge all custom controllers with. It contains `Base` class for custom controllers
|
241
|
+
* **Deps** - this is an abbreviation of "dependencies". This object has 2 properties:
|
242
|
+
* **cable** - if you want to send and receive signals / messages through WebSockets, assign consumer to this property by invoking `ActionCable.createConsumer();`
|
243
|
+
* **NotificationCenter** - you have to assign a custom class to this property that is going to receive notifications sent via WebSockets
|
244
|
+
* **Env** - this object holds environmental informations. Its properties:
|
245
|
+
* **action** - the value of the `data-action` attribute of `<body>`. This is also the name of the method that is called on the current controller
|
246
|
+
* **controller** - the instance of the current controller
|
247
|
+
* **namespaceController** - the instance of the current namespace controller
|
248
|
+
* **loco** - the instance of `Loco` (see _Initialization_ section). Its most important instance methods are:
|
249
|
+
* `getWire` - returns the current instance of `Wire`
|
250
|
+
* `setLocale` / `getLocale` - allows to set / get current locale
|
251
|
+
|
252
|
+
Look at [source code](https://github.com/locoframework/loco-js/blob/master/src/base/loco.coffee) for all.
|
253
|
+
* **Helpers** - the namespace where helpers are defined. Helpers are classes facilitating things like transforming text, converting numbers to currencies etc. Members:
|
254
|
+
* **Text** - has method(s) that returns *text* transformed into HTML by using simple formatting rules
|
255
|
+
* **I18n** - the object that holds localizations. Localizations are objects as well
|
256
|
+
* **Line** - the class responsible for sending and receiving messages over WebSocket connection
|
160
257
|
* **Loco** - this class rules everything ;)
|
161
|
-
* **Mix** -
|
162
|
-
* **Mixins** -
|
163
|
-
* **Models** -
|
164
|
-
* **Presenters** -
|
165
|
-
|
166
|
-
|
167
|
-
* **
|
168
|
-
|
169
|
-
* **
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
* **
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
258
|
+
* **Mix** - the factory function that generates a `Mixed` superclass (used for implementing mixins)
|
259
|
+
* **Mixins** - the namespace where mixins are defined
|
260
|
+
* **Models** - the object which all custom models should be merged with. It contains `Base` class for custom models
|
261
|
+
* **Presenters** - the empty object that you can merge your custom presenters with. Presenters can be used to hold functions used to present models or their attributes.
|
262
|
+
_Deprecated! It will be removed in the future. Store presenters on your own. This object doesn't have to be exported._
|
263
|
+
* **Services** - the namespace where service classes are defined. Members:
|
264
|
+
* **Date** - its instance methods are useful for converting `Date` to a string
|
265
|
+
* **UI** - the namespace where classes that interact with the HTML are defined. Members:
|
266
|
+
* **Form** - the class responsible for dealing with forms
|
267
|
+
* **Utils** - the namespace in which the classes containing the utility methods for the given data type are defined. Members: `Array`, `Collection`, `Dom`, `Object`, `String`
|
268
|
+
* **Validators** - the namespace where validators are defined and where custom validators should also be merged
|
269
|
+
* **Views** - the namespace where `Base` class for custom Views is defined
|
270
|
+
* **Wire** - the class responsible for fetching signals / notifications
|
271
|
+
|
272
|
+
# 📡 Models
|
273
|
+
|
274
|
+
The model layer has been extracted to a separate [repository](https://github.com/locoframework/loco-js-model) and it can be used standalone as well. If you want to look at how to integrate [React](https://reactjs.org), [Redux](https://redux.js.org) and **Loco-JS-Model**, 🎁[**this repository**](https://github.com/artofcodelabs/front-end-boilerplate)🎁 may be a good starting point.
|
275
|
+
|
276
|
+
## Nesting models 🏺
|
277
|
+
|
278
|
+
If you want to have two models with the same name or maybe you want to reflect a server architecture, you can even nest models. But only one-level nesting is allowed.
|
279
|
+
|
280
|
+
```javascript
|
281
|
+
// models/Coupon/Unit.js
|
282
|
+
|
283
|
+
import { Models } from "loco-js";
|
284
|
+
|
285
|
+
class Unit extends Models.Base {
|
286
|
+
static identity = "Coupon.Unit";
|
287
|
+
|
288
|
+
static remoteName = "Coupon::Unit"; // the name of the corresponding model
|
289
|
+
// on the server side (Ruby syntax)
|
290
|
+
|
291
|
+
static resources = {
|
292
|
+
// ...
|
293
|
+
};
|
294
|
+
|
295
|
+
static attributes = {
|
296
|
+
// ...
|
297
|
+
};
|
298
|
+
}
|
299
|
+
|
300
|
+
export default Unit;
|
190
301
|
```
|
191
302
|
|
192
|
-
|
303
|
+
Remember to merge all defined models with the exported `Models` object:
|
304
|
+
|
305
|
+
```javascript
|
306
|
+
// models/index.js
|
193
307
|
|
194
|
-
|
308
|
+
import { Models } from "loco-js";
|
195
309
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
App.Models.Article.find(id: 123).then (article) ->
|
200
|
-
# GET "/user/articles/123"
|
310
|
+
import Coupon from "./Coupon";
|
311
|
+
import Unit from "./Coupon/Unit";
|
312
|
+
import Admin from "./Admin";
|
201
313
|
|
202
|
-
|
203
|
-
|
314
|
+
Object.assign(Coupon, {
|
315
|
+
Unit
|
316
|
+
});
|
204
317
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
foo: 'bar',
|
210
|
-
baz: 'buz'
|
211
|
-
}).then (comment) ->
|
212
|
-
# GET "/user/articles/123/comments/33?foo=bar&baz=buz"
|
318
|
+
Object.assign(Models, {
|
319
|
+
Admin,
|
320
|
+
Coupon
|
321
|
+
});
|
213
322
|
```
|
214
323
|
|
215
|
-
|
324
|
+
Loco-JS will be able to find the correct model in this situation if you emit a signal for the corresponding model on the server side.
|
216
325
|
|
217
|
-
|
326
|
+
# 🕹 Controllers
|
218
327
|
|
219
|
-
|
220
|
-
* class methods: `@get` `@post` `@put` `@delete`
|
328
|
+
Like it's already been said - given method of given controller is called automatically based on HTML `<body>`'s attributes.
|
221
329
|
|
222
|
-
|
330
|
+
Exemplary controller:
|
223
331
|
|
224
|
-
```
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
332
|
+
```javascript
|
333
|
+
// controllers/admin/coupons.js
|
334
|
+
|
335
|
+
import { Controllers } from "loco-js";
|
336
|
+
|
337
|
+
import New from "views/admin/coupons/new";
|
338
|
+
import List from "views/admin/coupons/list";
|
339
|
+
|
340
|
+
class Coupons extends Controllers.Base {
|
341
|
+
static identity = "Coupons"; // persist the name of the class because
|
342
|
+
// it is going to be minified in production
|
343
|
+
// and knowing the name of the current controller
|
344
|
+
// can be useful (see the section about Line)
|
345
|
+
|
346
|
+
// Loco-JS supports static and instance methods
|
347
|
+
static index() {
|
348
|
+
new List().render();
|
349
|
+
}
|
350
|
+
|
351
|
+
new() {
|
352
|
+
const view = new New({ planId: this.params.id });
|
353
|
+
this.setView("new", view); // assigning the instance of currently rendered
|
354
|
+
// view to the controller's property gives
|
355
|
+
// a possibility to call other methods on it
|
356
|
+
// in the next life cycle
|
357
|
+
// (see the section about Line)
|
358
|
+
view.render();
|
359
|
+
}
|
360
|
+
}
|
229
361
|
|
230
|
-
|
231
|
-
article.put "publish", foo: 'bar', buz: 1
|
232
|
-
# PUT "/user/articles/43/publish"
|
233
|
-
# Parameters: {"foo"=>"bar", "buz"=>"1", "id"=>"43"}
|
362
|
+
export default Coupons;
|
234
363
|
```
|
235
364
|
|
236
|
-
|
365
|
+
To see all convenient properties and methods of the base class, other than `params` presented above, look at the [source code](https://github.com/locoframework/loco-js/blob/master/src/controllers/base.coffee).
|
237
366
|
|
238
|
-
|
367
|
+
Remember to merge all custom controllers with the `Controllers` object exported by Loco-JS (see the _Merging classes_ section). Optionally, you can use the namespace controller to set the default scope for models (`setResource` / `setScope`) methods.
|
239
368
|
|
240
|
-
|
369
|
+
# 🗺 Views
|
370
|
+
|
371
|
+
View is a layer where you should interact with the DOM to keep separation of concerns.
|
372
|
+
[Base class](https://github.com/locoframework/loco-js/blob/master/src/views/base.coffee) delivers only a few methods, so it does not force you how to do so.
|
373
|
+
The good practice is to always call `render` method on a view and treat it as a starting point.
|
374
|
+
You can even render **React** components inside of view.
|
375
|
+
|
376
|
+
```javascript
|
377
|
+
// views/admin/coupons/new.js
|
378
|
+
|
379
|
+
import { Views } from "loco-js";
|
380
|
+
import React from "react";
|
381
|
+
import { render as renderElement } from "react-dom";
|
382
|
+
|
383
|
+
import CouponForm from "components/admin/CouponForm";
|
384
|
+
import Coupon from "models/Coupon";
|
385
|
+
|
386
|
+
class New extends Views.Base {
|
387
|
+
constructor(opts) {
|
388
|
+
super(opts);
|
389
|
+
this.planId = opts.planId;
|
390
|
+
}
|
391
|
+
|
392
|
+
render() {
|
393
|
+
this.renderCouponForm();
|
394
|
+
}
|
395
|
+
|
396
|
+
renderCouponForm() {
|
397
|
+
const coupon = new Coupon({ resource: "admin", planId: this.planId });
|
398
|
+
renderElement(
|
399
|
+
<CouponForm coupon={coupon} />,
|
400
|
+
document.getElementById("coupon-form")
|
401
|
+
);
|
402
|
+
}
|
403
|
+
}
|
241
404
|
|
242
|
-
|
243
|
-
article = new App.Models.Article title: 'f'
|
244
|
-
article.isValid() # false
|
245
|
-
article.errors # {title: ["is too short (minimum is 3 characters)"], content: ["can't be blank"]}
|
405
|
+
export default New;
|
246
406
|
```
|
247
407
|
|
248
|
-
|
408
|
+
# 🔌 Connectivity
|
249
409
|
|
250
|
-
|
410
|
+
`Connectivity` is a mixin that is included in the `Base` classes of `Views` and `Controllers`. It allows you to send signals / notifications to all instances of controllers and views that are connected with given model classes or specific model instances. Example:
|
251
411
|
|
252
|
-
|
412
|
+
```javascript
|
413
|
+
// views/admin/coupons/list.js
|
414
|
+
|
415
|
+
import { Views } from "loco-js";
|
416
|
+
|
417
|
+
import Coupon from "models/Coupon";
|
418
|
+
|
419
|
+
class List extends Views.Base {
|
420
|
+
constructor(opts) {
|
421
|
+
super(opts);
|
422
|
+
}
|
423
|
+
|
424
|
+
async render() {
|
425
|
+
this.connectWith([Coupon]); // every time back-end emits signal for
|
426
|
+
// any coupon, receivedSignal method is called.
|
427
|
+
// An array of more than 1 model class can
|
428
|
+
// be passed as an argument. It is even possible
|
429
|
+
// to mix model classes and instances in this
|
430
|
+
// array
|
431
|
+
const coupons = await Coupon.get("all", { resource: "admin" });
|
432
|
+
this.connectWith(coupons.slice(-1), { // method lastCouponReceivedSignal
|
433
|
+
receiver: "lastCouponReceivedSignal" // is called only if a signal is
|
434
|
+
}); // emitted by the back-end for
|
435
|
+
// a specific Coupon instance
|
436
|
+
// that is the last element in
|
437
|
+
// "coupons" array at this moment
|
438
|
+
}
|
439
|
+
|
440
|
+
receivedSignal(signal, data) {
|
441
|
+
}
|
442
|
+
|
443
|
+
lastCouponReceivedSignal(signal, data) {
|
444
|
+
}
|
445
|
+
}
|
446
|
+
|
447
|
+
export default List;
|
448
|
+
```
|
449
|
+
|
450
|
+
So if you use Loco-Rails on the back-end and emit a signal for the first coupon in the database, like this:
|
451
|
+
|
452
|
+
```ruby
|
453
|
+
# you can do it anywhere, in rails console for example
|
454
|
+
include Loco::Emitter
|
455
|
+
emit Coupon.first, :updated, { data: { foo: 'bar' } }
|
456
|
+
```
|
457
|
+
|
458
|
+
On the front-end side:
|
459
|
+
|
460
|
+
1. Loco-JS will receive a signal in the following format `["Coupon", 1, "updated", {foo: "bar", id: 1}]`
|
461
|
+
2. `receivedSignal` method will be called for every instance of the above `List` class (there is only one usually) with `"Coupon updated"` and `{foo: "bar", id: 1}` as arguments
|
462
|
+
|
463
|
+
If you, on the other hand, emit signal for the last coupon in the database `emit Coupon.last, :updated, { data: { foo: 'bar' } }`
|
464
|
+
|
465
|
+
On the front-end side:
|
466
|
+
|
467
|
+
1. Loco-JS will receive a signal `["Coupon", 27, "updated", {foo: "bar", id: 27}]`
|
468
|
+
2. `lastCouponReceivedSignal` method will be called with `updated` and `{foo: "bar", id: 27}` as arguments
|
469
|
+
3. `receivedSignal` method will be called with `Coupon updated` and `{foo: "bar", id: 27}` as arguments
|
470
|
+
|
471
|
+
# 🚠 Wire
|
472
|
+
|
473
|
+
Instance of this class works internally and is responsible for fetching notifications.
|
474
|
+
The constructor takes an object whose many properties have been described in the *Initialization* section (look at the `notifications` property).
|
475
|
+
|
476
|
+
💥 In normal conditions, Wire checks and fetches notifications via AJAX polling. But if you have an established WebSocket connection _(see Line section)_, it will stop polling and will be waiting for informations, transmitted through WebSockets, about new, emitted by the back-end signals (to fetch them).
|
477
|
+
In case of losing the WebSocket connection, it can automatically switch to AJAX polling.
|
478
|
+
|
479
|
+
[All accessor methods](https://github.com/locoframework/loco-js/blob/master/src/base/wire.coffee) that may be useful are rather straightforward and self-explanatory. The one that requires a bit of explanation is `setToken`.
|
480
|
+
|
481
|
+
* `setToken(token)` - when token is set, it is automatically appended to the requests that fetch notifications. So it allows you to fetch notifications assigned to a given token. It is useful, when you want to emit a signal / notification, on the back-end, to a user that is not authenticated in the system _(e.g. you want to notify a user that he has confirmed his email address successfully via clicking on a link and is now able to sign in)_
|
482
|
+
|
483
|
+
```javascript
|
484
|
+
import { Env } from "loco-js";
|
485
|
+
const wire = Env.loco.getWire(); // this is how to grab a working instance
|
486
|
+
// of Wire during runtime and after
|
487
|
+
// initialization (see Initialization section)
|
488
|
+
wire.setToken("foobarbaz");
|
489
|
+
```
|
490
|
+
|
491
|
+
On the back-end, you can now emit a signal to _"this token"_. And only _this_ user will receive the following signal.
|
492
|
+
|
493
|
+
```ruby
|
494
|
+
include Loco::Emitter
|
495
|
+
emit Coupon.last, :updated, { data: { foo: 'bar' }, for: 'foobarbaz' }
|
496
|
+
```
|
497
|
+
|
498
|
+
# 〰 Line
|
499
|
+
|
500
|
+
Instance of this class works internally and is responsible for sending and receiving messages over WebSocket connection.
|
501
|
+
|
502
|
+
These messages are not what we call signals / notifications. Signals / notifications must be associated with instances of models on the back-end while messages sent via `Line` don't have this requirement and are directed directly to recipients.
|
503
|
+
|
504
|
+
It is not required to use Line when using Loco-JS. It works currently only if you use Loco-Rails on the back-end and it requires [Action Cable](https://www.npmjs.com/package/actioncable) as a front-end dependency.
|
505
|
+
|
506
|
+
Loco-JS automatically creates an instance of `Line` and it subscribes to `Loco::NotificationCenterChannel` if it discovers `ActionCable`'s consumer under `Deps.cable` exported by Loco-JS.
|
507
|
+
|
508
|
+
## Configuration 🛠
|
253
509
|
|
254
|
-
|
510
|
+
```javascript
|
511
|
+
import { Deps } from "loco-js";
|
512
|
+
import ActionCable from "actioncable";
|
513
|
+
|
514
|
+
// you can use one global NotificationCenter or per "panel"
|
515
|
+
import NotificationCenter from "services/admin/NotificationCenter";
|
255
516
|
|
256
|
-
|
257
|
-
|
258
|
-
switch signal
|
259
|
-
when 'updated'
|
260
|
-
@article.reload().then =>
|
261
|
-
@article.changes() # {title: {is: 'bar', was: 'foo'}, content: {is: 'buz', was: 'baz'}}
|
262
|
-
@article.applyChanges()
|
263
|
-
this.renderArticle()
|
517
|
+
Deps.cable = ActionCable.createConsumer();
|
518
|
+
Deps.NotificationCenter = NotificationCenter;
|
264
519
|
```
|
265
520
|
|
266
|
-
##
|
521
|
+
## Sending messages 🚚
|
522
|
+
|
523
|
+
You can send messages over WebSocket connection after initializing Loco-JS (see _Initialization_ section).
|
524
|
+
|
525
|
+
```javascript
|
526
|
+
import { Env } from "loco-js";
|
267
527
|
|
268
|
-
|
528
|
+
const line = Env.loco.getLine();
|
529
|
+
line.send({ foo: "bar" });
|
269
530
|
|
270
|
-
|
271
|
-
|
272
|
-
this.connectWith article, receiver: "_articleReceivedSignal"
|
531
|
+
// or using shortcut
|
532
|
+
Env.loco.emit({ baz: "buz"});
|
273
533
|
```
|
274
534
|
|
275
|
-
|
535
|
+
To see how to receive messages on the back-end, look at the [Loco-Rails documentation](https://github.com/locoframework/loco-rails#notification-center).
|
276
536
|
|
277
|
-
|
537
|
+
## Receiving messages 📩
|
278
538
|
|
279
|
-
|
539
|
+
Every time the back-end emits a signal to the front-end like this:
|
280
540
|
|
281
|
-
|
541
|
+
```ruby
|
542
|
+
include Loco::Emitter
|
543
|
+
# emit_to method emits message over WebSocket connection
|
544
|
+
# to all signed in admins (in this example)
|
545
|
+
emit_to Admin.all, type: 'COUPON_CREATED', id: @coupon.id
|
546
|
+
```
|
282
547
|
|
283
|
-
`
|
548
|
+
`receivedSignal` static or instance method is called on `Deps.NotificationCenter` class.
|
284
549
|
|
285
|
-
|
286
|
-
|
550
|
+
```javascript
|
551
|
+
// services/admin/NotificationCenter.js
|
552
|
+
|
553
|
+
import { Env } from "loco-js";
|
554
|
+
|
555
|
+
class NotificationCenter {
|
556
|
+
static receivedSignal(data) {
|
557
|
+
switch (data.type) {
|
558
|
+
case "COUPON_CREATED":
|
559
|
+
this.couponCreated(data.id);
|
560
|
+
break;
|
561
|
+
default:
|
562
|
+
}
|
563
|
+
}
|
564
|
+
|
565
|
+
static couponCreated(couponId) {
|
566
|
+
// break if current controller is not Coupons
|
567
|
+
if (Env.controller.constructor.identity !== "Coupons") return;
|
568
|
+
|
569
|
+
// break if current action is not "new"
|
570
|
+
if (Env.action !== "new") return;
|
571
|
+
|
572
|
+
// call couponCreated method on the view - assigned to the current
|
573
|
+
// controller as "new" by using setView method inherited
|
574
|
+
// from the Controllers.Base class
|
575
|
+
Env.controller.getView("new").couponCreated(couponId);
|
576
|
+
}
|
577
|
+
}
|
287
578
|
|
288
|
-
|
579
|
+
export default NotificationCenter;
|
580
|
+
```
|
289
581
|
|
290
|
-
|
582
|
+
# ⬇️ Previous doc
|
291
583
|
|
292
584
|
## App.UI.Form
|
293
585
|
|
@@ -332,57 +624,39 @@ Example:
|
|
332
624
|
</form>
|
333
625
|
```
|
334
626
|
|
335
|
-
|
336
|
-
|
337
|
-
Instance of this class works internally and is responsible for fetching notifications. Following code shows - how to get this instance during runtime:
|
338
|
-
|
339
|
-
```coffeescript
|
340
|
-
App.Env.loco.getWire()
|
341
|
-
```
|
627
|
+
TODO: JS example + how it works desc
|
342
628
|
|
343
|
-
|
344
|
-
|
345
|
-
## App.Line (since ver. 1.3)
|
346
|
-
|
347
|
-
Instance of this class works internally and is responsible for sending and receiving messages over WebSocket connection. Loco-JS automatically creates instance of `App.Line` and subscribes to `Loco::NotificationCenterChannel` if discovers `ActionCable`'s consumer under `App.cable`. Following code shows - how to get this instance during runtime:
|
629
|
+
## Development
|
348
630
|
|
349
|
-
|
350
|
-
App.Env.loco.getLine()
|
351
|
-
```
|
631
|
+
### Development and testing
|
352
632
|
|
353
|
-
|
633
|
+
Look inside `gulpfile.js` for more details.
|
354
634
|
|
355
|
-
|
356
|
-
App.Env.loco.getLine().send({})
|
635
|
+
## Examples
|
357
636
|
|
358
|
-
|
359
|
-
App.Env.loco.emit({})
|
360
|
-
```
|
637
|
+
* examine `test/dummy` app inside [Loco-Rails project](http://github.com/locoframework/loco-rails) for real-life use cases of almost all Loco's features in various scenarios
|
361
638
|
|
362
|
-
|
639
|
+
# 👩🏽🔬 Tests
|
363
640
|
|
364
|
-
|
641
|
+
...
|
365
642
|
|
366
|
-
|
367
|
-
class App.Services.NotificationCenter
|
368
|
-
receivedSignal: (data) ->
|
369
|
-
```
|
643
|
+
# 📈 Changelog
|
370
644
|
|
371
|
-
|
645
|
+
## Major releases 🎙
|
372
646
|
|
373
|
-
|
647
|
+
### 1.5
|
374
648
|
|
375
|
-
|
649
|
+
* Loco-JS dropped the dependency on jQuery. So it has no external dependencies officially 🎉
|
376
650
|
|
377
|
-
|
651
|
+
Informations about all releases are published on [Twitter](https://twitter.com/artofcode_co)
|
378
652
|
|
379
|
-
|
653
|
+
### 1.3
|
380
654
|
|
381
|
-
*
|
655
|
+
* Line
|
382
656
|
|
383
|
-
|
657
|
+
# License 📜
|
384
658
|
Loco-JS is released under the [MIT License](https://opensource.org/licenses/MIT).
|
385
659
|
|
386
|
-
|
660
|
+
# Author 👨🏭
|
387
661
|
|
388
662
|
Zbigniew Humeniuk from [Art of Code](http://artofcode.co)
|