Joerg Sprave’s Archery Extreme

Joerg Sprave’s Archery Extreme

https://ift.tt/2NRUGhQ

Joerg Sprave’s Archery Extreme

Link

There’s nothing quite as joyous as the grin on Joerg Sprave’s face and his manaical laugh when he fires up one of his over-the-top homebrew weapons. In this clip, he shows off a few of his creations, a couple of commercially-available crossbows, and the real reason you came here, an insane drill-powered machine bow at 7:15.

fun

via The Awesomer https://theawesomer.com

January 22, 2020 at 01:15PM

The Best Ergonomic Keyboard

The Best Ergonomic Keyboard

https://ift.tt/2TPOoDg

The Best Ergonomic Keyboard

Ergonomic keyboards are designed to reduce strain by keeping your hands, wrists, and arms at more comfortable, natural positions than you can get with a standard keyboard. After spending months testing 10 of them, we recommend the Kinesis Freestyle Edge RGB for anyone who does a lot of typing and is concerned about their posture or about hand, arm, or shoulder pain.

technology

via Wirecutter: Reviews for the Real World https://ift.tt/2gcK1uO

January 22, 2020 at 02:20PM

After Senseless Murder Of Goliath, Philistines Call For Ban On Fully Automatic, High-Capacity Slings

After Senseless Murder Of Goliath, Philistines Call For Ban On Fully Automatic, High-Capacity Slings

https://ift.tt/3avbgOq

After Senseless Murder Of Goliath, Philistines Call For Ban On Fully Automatic, High-Capacity Slings

VALLEY OF ELAH—After local homegrown terrorist David slew Goliath with a fully automatic, high-capacity sling, Philistine activists began calling for common-sense bans on the dangerous weapons of mass destruction.

“Nobody needs a sling that holds five rocks just to go hunting or protect their sheep,” said one Philistine woman with pink hair and several face piercings. “This tragedy could have been avoided if only David were forced to use one of the old bolt-action model slings.”

Investigators believe the shepherd boy, radicalized by religious texts, built up an arsenal of approximately five hollow-point, armor-piercing rocks, “a deadly stockpile.”

“Can you imagine if he had opened fire in a crowded market or around the village well?”

Many Philistines offered “thoughts and prayers” to Dagon, but activists continue to insist “your thoughts and prayers are not enough.”

Breaking: Paypal Now Available

Many of you told us you wouldn’t subscribe until we offered Paypal as a payment option. You apparently weren’t bluffing, so we finally caved and added Paypal. Now — like the unbeliever faced with God’s invisible qualities displayed in nature — you are without excuse.

fun

via The Babylon Bee https://babylonbee.com

January 21, 2020 at 11:38AM

Find the Large Attachments Eating Up Your Gmail Space With a Simple Search

Find the Large Attachments Eating Up Your Gmail Space With a Simple Search

https://ift.tt/2TL4vSL

Have you ever had to frantically delete photos from your phone’s camera roll to make room for new ones? Us too. If you run up against your storage limit in Gmail, you won’t be able to send or receive new messages—a problem that’s just as frustrating.

Your Google storage allotment is shared across Drive, Gmail, and Photos, and there are a number of ways to make space from app to app. Messages and attachments (including those in Spam and Trash folders) are the big storage hogs in Gmail, so here’s how to find and delete those oversized attachments.

To start, type has:attachment larger:10MB in the Search box at the top of the Gmail window on your desktop or laptop web browser. This will turn up messages with attachments over 10 megabytes. Change the number around as needed (or save yourself a character by omitting the “B” in “MB,” if you want). You can’t search in GB, or gigabytes, but Gmail doesn’t let you send files that large anyway—you’re limited to 25MB of attachments in each message.

You can also use the size search operator, if you’d rather specify file sizes in bytes. Simply type size: and then a minimum number of bytes, such as size:1000000 (or 1MB). Here are a few examples, which you can click to see the results in your inbox immediately:

To free up storage space, select the messages you want to delete and click the Trash icon. Then, find your Trash folder on the left menu (you may have to select More > Trash depending on your inbox organization) and click “Empty Trash Now.”

You can see how much storage you have (and how much you’re using) if you scroll to the bottom of your inbox. Alternatively, go to your Drive settings to view how much space each app is using.

This piece was originally published in November 2012 and updated in January 2020 with more current information.

geeky,Tech,Database

via Lifehacker https://lifehacker.com

January 21, 2020 at 04:38PM

Moving from MySQL 5.7 to MySQL 8.0 – What You Should Know

Moving from MySQL 5.7 to MySQL 8.0 – What You Should Know

https://ift.tt/2NLpDUQ

April 2018 is not just a date for the MySQL world. MySQL 8.0 was released there, and more than 1 year after, it’s probably time to consider migrating to this new version.

MySQL 8.0 has important performance and security improvements, and, as in all migration to a new database version, there are several things to take into account before going into production to avoid hard issues like data loss, excessive downtime, or even a rollback during the migration task.

In this blog, we’ll mention some of the new MySQL 8.0 features, some deprecated stuff, and what you need to keep in mind before migrating.

What’s New in MySQL 8.0?

Let’s now summarize some of the most important features mentioned in the official documentation for this new MySQL version.

  • MySQL incorporates a transactional data dictionary that stores information about database objects.
  • An atomic DDL statement combines the data dictionary updates, storage engine operations, and binary log writes associated with a DDL operation into a single, atomic transaction.
  • The MySQL server automatically performs all necessary upgrade tasks at the next startup to upgrade the system tables in the mysql schema, as well as objects in other schemas such as the sys schema and user schemas. It is not necessary for the DBA to invoke mysql_upgrade.
  • It supports the creation and management of resource groups, and permits assigning threads running within the server to particular groups so that threads execute according to the resources available to the group. 
  • Table encryption can now be managed globally by defining and enforcing encryption defaults. The default_table_encryption variable defines an encryption default for newly created schemas and general tablespace. Encryption defaults are enforced by enabling the table_encryption_privilege_check variable. 
  • The default character set has changed from latin1 to utf8mb4.
  • It supports the use of expressions as default values in data type specifications. This includes the use of expressions as default values for the BLOB, TEXT, GEOMETRY, and JSON data types.
  • Error logging was rewritten to use the MySQL component architecture. Traditional error logging is implemented using built-in components, and logging using the system log is implemented as a loadable component.
  • A new type of backup lock permits DML during an online backup while preventing operations that could result in an inconsistent snapshot. The new backup lock is supported by LOCK INSTANCE FOR BACKUP and UNLOCK INSTANCE syntax. The BACKUP_ADMIN privilege is required to use these statements.
  • MySQL Server now permits a TCP/IP port to be configured specifically for administrative connections. This provides an alternative to the single administrative connection that is permitted on the network interfaces used for ordinary connections even when max_connections connections are already established.
  • It supports invisible indexes. This index is not used by the optimizer and makes it possible to test the effect of removing an index on query performance, without removing it.
  • Document Store for developing both SQL and NoSQL document applications using a single database.
  • MySQL 8.0 makes it possible to persist global, dynamic server variables using the SET PERSIST command instead of the usual SET GLOBAL one. 

MySQL Security and Account Management

As there are many improvements related to security and user management, we’ll list them in a separate section.

  • The grant tables in the mysql system database are now InnoDB tables. 
  • The new caching_sha2_password authentication plugin is now the default authentication method in MySQL 8.0. It implements SHA-256 password hashing, but uses caching to address latency issues at connect time. It provides more secure password encryption than the mysql_native_password plugin, and provides better performance than sha256_password.
  • MySQL now supports roles, which are named collections of privileges. Roles can have privileges granted to and revoked from them, and they can be granted to and revoked from user accounts. 
  • MySQL now maintains information about password history, enabling restrictions on reuse of previous passwords. 
  • It enables administrators to configure user accounts such that too many consecutive login failures due to incorrect passwords cause temporary account locking. 

InnoDB enhancements

As the previous point, there are also many improvements related to this topic, so we’ll list them in a separate section too.

  • The current maximum auto-increment counter value is written to the redo log each time the value changes, and saved to an engine-private system table on each checkpoint. These changes make the current maximum auto-increment counter value persistent across server restarts
  • When encountering index tree corruption, InnoDB writes a corruption flag to the redo log, which makes the corruption flag crash-safe. InnoDB also writes in-memory corruption flag data to an engine-private system table on each checkpoint. During recovery, InnoDB reads corruption flags from both locations and merges results before marking in-memory table and index objects as corrupt.
  • A new dynamic variable, innodb_deadlock_detect, may be used to disable deadlock detection. On high concurrency systems, deadlock detection can cause a slowdown when numerous threads wait for the same lock. At times, it may be more efficient to disable deadlock detection and rely on the innodb_lock_wait_timeout setting for transaction rollback when a deadlock occurs.
  • InnoDB temporary tables are now created in the shared temporary tablespace, ibtmp1.
  • mysql system tables and data dictionary tables are now created in a single InnoDB tablespace file named mysql.ibd in the MySQL data directory. Previously, these tables were created in individual InnoDB tablespace files in the mysql database directory.
  • By default, undo logs now reside in two undo tablespaces that are created when the MySQL instance is initialized. Undo logs are no longer created in the system tablespace.
  • The new innodb_dedicated_server variable, which is disabled by default, can be used to have InnoDB automatically configure the following options according to the amount of memory detected on the server: innodb_buffer_pool_size, innodb_log_file_size, and innodb_flush_method. This option is intended for MySQL server instances that run on a dedicated server. 
  • Tablespace files can be moved or restored to a new location while the server is offline using the innodb_directories option. 

Now, let’s take a look at some of the features that you shouldn’t use anymore in this new MySQL version.

What is Deprecated in MySQL 8.0?

The following features are deprecated and will be removed in a future version.

  • The utf8mb3 character set is deprecated. Please use utf8mb4 instead.
  • Because caching_sha2_password is the default authentication plugin in MySQL 8.0 and provides a superset of the capabilities of the sha256_password authentication plugin, sha256_password is deprecated.
  • The validate_password plugin has been reimplemented to use the server component infrastructure. The plugin form of validate_password is still available but is deprecated.
  • The ENGINE clause for the ALTER TABLESPACE and DROP TABLESPACE statements.
  • The PAD_CHAR_TO_FULL_LENGTH SQL mode.
  • AUTO_INCREMENT support is deprecated for columns of type FLOAT and DOUBLE (and any synonyms). Consider removing the AUTO_INCREMENT attribute from such columns, or convert them to an integer type.
  • The UNSIGNED attribute is deprecated for columns of type FLOAT, DOUBLE, and DECIMAL (and any synonyms). Consider using a simple CHECK constraint instead for such columns.
  • FLOAT(M,D) and DOUBLE(M,D) syntax to specify the number of digits for columns of type FLOAT and DOUBLE (and any synonyms) is a nonstandard MySQL extension. This syntax is deprecated.
  • The nonstandard C-style &&, ||, and ! operators that are synonyms for the standard SQL AND, OR, and NOT operators, respectively, are deprecated. Applications that use the nonstandard operators should be adjusted to use the standard operators.
  • The mysql_upgrade client is deprecated because its capabilities for upgrading the system tables in the mysql system schema and objects in other schemas have been moved into the MySQL server.
  • The mysql_upgrade_info file, which is created data directory and used to store the MySQL version number.
  • The relay_log_info_file system variable and –master-info-file option are deprecated. Previously, these were used to specify the name of the relay log info log and master info log when relay_log_info_repository=FILE and master_info_repository=FILE were set, but those settings have been deprecated. The use of files for the relay log info log and master info log has been superseded by crash-safe slave tables, which are the default in MySQL 8.0.
  • The use of the MYSQL_PWD environment variable to specify a MySQL password is deprecated.

And now, let’s take a look at some of the features that you must stop using in this MySQL version.

What Was Removed in MySQL 8.0?

The following features have been removed in MySQL 8.0.

  • The innodb_locks_unsafe_for_binlog system variable was removed. The READ COMMITTED isolation level provides similar functionality.
  • Using GRANT to create users. Instead, use CREATE USER. Following this practice makes the NO_AUTO_CREATE_USER SQL mode immaterial for GRANT statements, so it too is removed, and an error now is written to the server log when the presence of this value for the sql_mode option in the options file prevents mysqld from starting.
  • Using GRANT to modify account properties other than privilege assignments. This includes authentication, SSL, and resource-limit properties. Instead, establish such properties at account-creation time with CREATE USER or modify them afterward with ALTER USER.
  • IDENTIFIED BY PASSWORD ‘auth_string’ syntax for CREATE USER and GRANT. Instead, use IDENTIFIED WITH auth_plugin AS ‘auth_string’ for CREATE USER and ALTER USER, where the ‘auth_string’ value is in a format compatible with the named plugin. 
  • The PASSWORD() function. Additionally, PASSWORD() removal means that SET PASSWORD … = PASSWORD(‘auth_string’) syntax is no longer available.
  • The old_passwords system variable.
  • The FLUSH QUERY CACHE and RESET QUERY CACHE statements.
  • These system variables: query_cache_limit, query_cache_min_res_unit, query_cache_size, query_cache_type, query_cache_wlock_invalidate.
  • These status variables: Qcache_free_blocks, Qcache_free_memory, Qcache_hits, Qcache_inserts, Qcache_lowmem_prunes, Qcache_not_cached, Qcache_queries_in_cache, Qcache_total_blocks.
  • These thread states: checking privileges on cached query, checking query cache for a query, invalidating query cache entries, sending cached result to the client, storing result in the query cache, Waiting for query cache lock.
  • The tx_isolation and tx_read_only system variables have been removed. Use transaction_isolation and transaction_read_only instead.
  • The sync_frm system variable has been removed because .frm files have become obsolete.
  • The secure_auth system variable and –secure-auth client option have been removed. The MYSQL_SECURE_AUTH option for the mysql_options() C API function was removed.
  • The log_warnings system variable and –log-warnings server option have been removed. Use the log_error_verbosity system variable instead.
  • The global scope for the sql_log_bin system variable was removed. sql_log_bin has session scope only, and applications that rely on accessing @@GLOBAL.sql_log_bin should be adjusted.
  • The unused date_format, datetime_format, time_format, and max_tmp_tables system variables are removed.
  • The deprecated ASC or DESC qualifiers for GROUP BY clauses are removed. Queries that previously relied on GROUP BY sorting may produce results that differ from previous MySQL versions. To produce a given sort order, provide an ORDER BY clause.
  • The parser no longer treats \N as a synonym for NULL in SQL statements. Use NULL instead. This change does not affect text file import or export operations performed with LOAD DATA or SELECT … INTO OUTFILE, for which NULL continues to be represented by \N. 
  • The client-side –ssl and –ssl-verify-server-cert options have been removed. Use –ssl-mode=REQUIRED instead of –ssl=1 or –enable-ssl. Use –ssl-mode=DISABLED instead of –ssl=0, –skip-ssl, or –disable-ssl. Use –ssl-mode=VERIFY_IDENTITY instead of –ssl-verify-server-cert options.
  • The mysql_install_db program has been removed from MySQL distributions. Data directory initialization should be performed by invoking mysqld with the –initialize or –initialize-insecure option instead. In addition, the –bootstrap option for mysqld that was used by mysql_install_db was removed, and the INSTALL_SCRIPTDIR CMake option that controlled the installation location for mysql_install_db was removed.
  • The mysql_plugin utility was removed. Alternatives include loading plugins at server startup using the –plugin-load or –plugin-load-add option, or at runtime using the INSTALL PLUGIN statement.
  • The resolveip utility is removed. nslookup, host, or dig can be used instead.

There are a lot of new, deprecated, and removed features. You can check the official website for more detailed information.

Considerations Before Migrating to MySQL 8.0

Let’s mention now some of the most important things to consider before migrating to this MySQL version.

Authentication Method

As we mentioned, caching_sha2_password is not the default authentication method, so you should check if your application/connector supports it. If not, let’s see how you can change the default authentication method and the user authentication plugin to ‘mysql_native_password’ again.

To change the default  authentication method, edit the my.cnf configuration file, and add/edit the following line:

$ vi /etc/my.cnf

[mysqld]

default_authentication_plugin=mysql_native_password

To change the user authentication plugin, run the following command with a privileged user:

$ mysql -p

ALTER USER ‘username’@’hostname’ IDENTIFIED WITH ‘mysql_native_password’ BY ‘password’;

Anyway, these changes aren’t a permanent solution as the old authentication could be deprecated soon, so you should take it into account for a future database upgrade.

Also the roles are an important feature here. You can reduce the individual privileges assigning it to a role and adding the corresponding users there. 

For example, you can create a new role for the marketing and the developers teams:

$ mysql -p

CREATE ROLE 'marketing', 'developers';

Assign privileges to these new roles:

GRANT SELECT ON *.* TO 'marketing';

GRANT ALL PRIVILEGES ON *.* TO 'developers';

And then, assign the role to the users:

GRANT 'marketing' TO 'marketing1'@'%';

GRANT 'marketing' TO 'marketing2'@'%';

GRANT 'developers' TO 'developer1'@'%';

And that’s it. You’ll have the following privileges:

SHOW GRANTS FOR 'marketing1'@'%';

+-------------------------------------------+

| Grants for marketing1@%                   |

+-------------------------------------------+

| GRANT USAGE ON *.* TO `marketing1`@`%`    |

| GRANT `marketing`@`%` TO `marketing1`@`%` |

+-------------------------------------------+

2 rows in set (0.00 sec)

SHOW GRANTS FOR 'marketing';

+----------------------------------------+

| Grants for marketing@%                 |

+----------------------------------------+

| GRANT SELECT ON *.* TO `marketing`@`%` |

+----------------------------------------+

1 row in set (0.00 sec)

Character Sets

As the new default character set is utf8mb4, you should make sure you’re not using the default one as it’ll change.

To avoid some issues, you should specify the character_set_server and the collation_server variables in the my.cnf configuration file.

$ vi /etc/my.cnf

[mysqld]

character_set_server=latin1

collation_server=latin1_swedish_ci

MyISAM Engine

The MySQL privilege tables in the MySQL schema are moved to InnoDB. You can create a table engine=MyISAM, and it will work as before, but coping a MyISAM table into a running MySQL server will not work because it will not be discovered.

Partitioning

There must be no partitioned tables that use a storage engine that does not have native partitioning support. You can run the following query to verify this point.

$ mysql -p

SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE NOT IN ('innodb', 'ndbcluster') AND CREATE_OPTIONS LIKE '%partitioned%';

If you need to change the engine of a table, you can run:

ALTER TABLE table_name ENGINE = INNODB;

Upgrade Check

As a last step, you can run the mysqlcheck command using the check-upgrade flag to confirm if everything looks fine.

$ mysqlcheck -uroot -p --all-databases --check-upgrade

Enter password:

mysql.columns_priv                                 OK

mysql.component                                    OK

mysql.db                                           OK

mysql.default_roles                                OK

mysql.engine_cost                                  OK

mysql.func                                         OK

mysql.general_log                                  OK

mysql.global_grants                                OK

mysql.gtid_executed                                OK

mysql.help_category                                OK

mysql.help_keyword                                 OK

mysql.help_relation                                OK

mysql.help_topic                                   OK

mysql.innodb_index_stats                           OK

mysql.innodb_table_stats                           OK

mysql.password_history                             OK

mysql.plugin                                       OK

mysql.procs_priv                                   OK

mysql.proxies_priv                                 OK

mysql.role_edges                                   OK

mysql.server_cost                                  OK

mysql.servers                                      OK

mysql.slave_master_info                            OK

mysql.slave_relay_log_info                         OK

mysql.slave_worker_info                            OK

mysql.slow_log                                     OK

mysql.tables_priv                                  OK

mysql.time_zone                                    OK

mysql.time_zone_leap_second                        OK

mysql.time_zone_name                               OK

mysql.time_zone_transition                         OK

mysql.time_zone_transition_type                    OK

mysql.user                                         OK

sys.sys_config                                     OK

world_x.city                                       OK

world_x.country                                    OK

world_x.countryinfo                                OK

world_x.countrylanguage                            OK

There are several things to check before performing the upgrade. You can check the official MySQL documentation for more detailed information.

Upgrade Methods

There are different ways to upgrade MySQL 5.7 to 8.0. You can use the upgrade in-place or even create a replication slave in the new version, so you can promote it later. 

But before upgrading, step 0 must be backing up your data. The backup should include all the databases including the system databases. So, if there is any issue, you can rollback asap. 

Another option, depending on the available resources, can be creating a cascade replication MySQL 5.7 -> MySQL 8.0 -> MySQL 5.7, so after promoting the new version, if something went wrong, you can promote the slave node with the old version back. But it could be dangerous if there was some issue with the data, so the backup is a must before it.

For any method to be used, it’s necessary a test environment to verify that the application is working without any issue using the new MySQL 8.0 version.

Conclusion

More than 1 year after the MySQL 8.0 release, it is time to start thinking to migrate your old MySQL version, but luckily, as the end of support for MySQL 5.7 is 2023, you have time to create a migration plan and test the application behavior with no rush. Spending some time in that testing step is necessary to avoid any issue after migrating it.

technology

via Planet MySQL https://ift.tt/2iO8Ob8

January 21, 2020 at 04:50PM

iCal Library for PHP

iCal Library for PHP

https://ift.tt/38w9B9z

iCal Library for PHP

Markus Poerschke has PHP package that provides an abstraction layer for creating iCalendars:

use Eluceo\iCal\Component\Calendar; use Eluceo\iCal\Component\Event; $vCalendar = new Calendar('www.example.com'); $vCalendar->setName('Example Calendar'); $vCalendar->setTimezone('America/New_York'); $vEvent = new Event(); $vEvent ->setDtStart(new \DateTime('2012-12-24')) ->setDtEnd(new \DateTime('2012-12-24')) ->setNoTime(true) ->setSummary('Christmas'); $vCalendar->addComponent($vEvent); header('Content-Type: text/calendar; charset=utf-8'); header('Content-Disposition: attachment; filename="cal.ics"'); echo $vCalendar->render(); 

The library supports the following iCalendar components:

  • VCALENDAR
  • VEVENT
  • VALARM
  • VTIMEZONE

After incorporating it in your application, here’s an example of linking to a calendar:

<a href="webcal://www.example.com/holidays.ics">Subscribe (iCal)</a> 

You can learn more about this package, get full installation instructions, and view the source code on GitHub at markuspoerschke/iCal.

Filed in: News

programming

via Laravel News https://ift.tt/14pzU0d

January 21, 2020 at 09:23AM

SHOT Show: Uintah Precision Bolt-Action AR Uppers

SHOT Show: Uintah Precision Bolt-Action AR Uppers

https://ift.tt/2O0aNu7

It’s a hard thing to accept, but shooters in rights-restrictive states simply cannot own (or will not be able to own) semi-auto modern sporting rifles, mainly those based on the AR-15 design. But they can usually own manually-operated actions, such as those manufactured by Uintah Precision.

Uintah Precision produces bolt-action, precision upper receivers for AR pattern rifles. Compatible with LR-308 and AR-15 platform rifles, UPR10 and UPR15 bolt-action uppers simply pin in place on an existing upper receiver. No modifications or changes are needed to your lower receiver and they feed from standard magazines. They are available in both left- and right-handed configurations.

 

 

Standard offerings for the UPR15 are 223 Wylde, 300 BLK, 6.5 Grendel, and 224 Valkyrie.

Standard offerings for the UPR10 are 243, 308, 6mm Creedmoor and 6.5 Creedmoor.

UPR10 uppers currently come standard with Shilen, No. 5 profile, match grade barrels and have a 20-MOA rail machined into them.

UPR15 uppers come standard with barrels produced from Preferred Barrels blanks and are a flat top railed upper.

The bolts are three-lug designs machined from 4140 American steel and utilize a Savage-style extractor.

Both models are compatible with most aftermarket accessories.

This year, Uintah Precision is debuting complete bolt-action AR rifles. They feature matched uppers and lowers both designed and produced in house. Price: Price: $1088.

guns

via The Truth About Guns https://ift.tt/1TozHfp

January 20, 2020 at 08:01PM

Generate PDF from HTML Using Laravel Snappy Package

Generate PDF from HTML Using Laravel Snappy Package

https://www.youtube.com/watch?v=P43fuBbmD1c

In this tutorial, you will learn how to create a pdf file from an HTML markup or blade view file in Laravel with examples.

programming

via Laravel News Links https://ift.tt/2dvygAJ

January 17, 2020 at 09:06AM

Programming Katas Explained

Programming Katas Explained

https://ift.tt/2qJfgc7

Kata is a martial arts term from Japan that refers to a choreographed sequence of movements. The goal is to perfect and internalize these movements through repetition and memorization. Once mastered, these sequences serve as a reference guide that you can instantly reach for and adapt without thought.

Outside of martial arts, this word, kata, is used more generally to refer to any set of steps or patterns that is repeated until mastery. Think of it as a way to harness your form and routine.

Published on Jan 15th, 2020.

programming

via Laracasts https://ift.tt/1eZ1zac

January 17, 2020 at 01:08PM