#Static Pass Box exporter
Explore tagged Tumblr posts
airomaxairbornellp · 3 days ago
Text
Static Pass Box: Contamination-Free Material Transfer for Cleanrooms
Airomax Airborne LLP is a leading manufacturer of static pass box in India, providing contamination-free solutions for cleanrooms and controlled environments. Designed for safe material transfer, these pass boxes prevent airborne contaminants from entering critical areas, ensuring high standards of cleanliness in pharmaceutical, biotechnology, and electronics industries.
Tumblr media
Built with high-quality stainless steel, Airomax Airborne LLP’s static pass boxes offer durability and corrosion resistance. They feature interlocking doors, UV sterilization, and HEPA filtration, ensuring a secure and controlled transfer process. Their user-friendly design and smooth surface finish allow for easy cleaning and maintenance, making them an ideal choice for sterile environments.
Airomax Airborne LLP combines precision engineering with advanced technology to deliver reliable pass box solutions tailored to industry-specific requirements. Whether for laboratories, hospitals, or manufacturing units, their pass boxes enhance cleanliness and minimize cross-contamination risks.
For more details, visit Airomax Airborne LLP or contact +91-7567138386 to explore high-quality static pass box solutions for your cleanroom facility.
0 notes
dlktech24 · 4 months ago
Text
Static Pass Box exporter in Chennai
As a trusted Static Pass Box exporter in Chennai, PMA Systems & Solutions offers high-quality, reliable pass boxes for safe and efficient material transfer. Designed to meet stringent hygiene and safety standards, their static pass boxes ensure contamination-free handling in clean rooms, labs, and controlled environments. With precision engineering, these pass boxes are built for durability and long-lasting performance. PMA Systems & Solutions provides customized solutions, ensuring each pass box meets the specific requirements of your industry. Their expert team ensures timely delivery and top-notch customer service. Choose PMA Systems & Solutions for your Static Pass Box export needs in Chennai, ensuring safety and efficiency in every transaction.
0 notes
midseo · 16 days ago
Text
Fine Filter, Fine Air Industrial Filter Manufacturer, Exporter, India
Fine Filter : We are Fine Filter manufacturer, Fine Filter supplier in mumbai, India. Call Now.
Cleanroom Turnkey Project, Air Handling Unit, HVAC Ducting, HVAC Terminal Box, Electric Control Panel for AHU, Epoxy & Coving, Clean Room PUF Partition, Clean Room Door, Cleanroom Equipment, Dispensing Booth, Sampling Booth, Laminar Air Flow, Horizontal Laminar Air Flow, Vertical Laminar Air Flow, Mobile Trolley Laminar Air Flow, Laminar Air Flow for Operation Theatres, Static Pass Box, Dynamic Pass Box (2 Way),(3 Way), Biosafety Cabinet Class - II A2, Biosafety Cabinet Class - II B2, Static Garment Cubical, Dynamic Garment Cubical, Single Door Air Shower (2 Way), Double Door Air Shower (2 Way), HVAC Filters, Pre Filter, Fine Filter, Absolute HEPA Filter, Super HEPA Filter, Activated Carbon Filter, Miniplast HEPA Filter (Gasket), Miniplast HEPA Filter (Gel Seal), Combination Filter, Pocket Filter, Bag Filter, Modular Furniture, Modular Operation Theatre.
0 notes
harmonyos-next · 3 months ago
Text
HarmonyOS NEXT Practical: Custom Confirmation Pop up
Objective: Encapsulate custom pop ups and directly open customized confirmation pop ups through method calls.
Knowledge points:
Due to various limitations in the use of the Customs Dialogue Controller, it does not support dynamic creation or refresh. In relatively complex application scenarios, it is recommended to use the openCustoms Dialog interface provided by the PromptAction object obtained from UIContext to implement custom pop ups.
The openCustoms dialog can be configured with isModal to achieve modal and non modal pop ups. When isModal is true, the pop-up box is a modal pop-up window. When isModal is false, the pop-up box is a non modal pop-up window.
Opening and closing custom pop ups:
Create WidgetContent. WidgetContent is used to define the content of custom pop ups. Among them, wrapBuilder (buildText) encapsulates custom components, and new Params (this. message) is the input parameter for custom components, which can be defaulted or passed in as the basic data type.
Open the custom pop-up box. The pop-up box opened by calling the openCustomizalDialog interface defaults to a pop-up box with customStyle set to true, which means that the content style of the pop-up box is displayed completely according to the contentNode custom style.
Close the custom pop-up box. Due to the need to pass in the Component Content corresponding to the pop-up box to be closed for the closeCustoms Dialog interface. Therefore, if you need to set a closing method in the pop-up box, you can refer to the complete example to encapsulate the static method for implementation. If you need to release the corresponding WidgetContent after closing the pop-up box, you need to call the dispose method of WidgetContent.
Actual combat: PromptActionClass [code] import { BusinessError } from '@kit.BasicServicesKit'; import { ComponentContent, promptAction } from '@kit.ArkUI'; import { UIContext } from '@ohos.arkui.UIContext';
export class PromptActionClass { static ctx: UIContext; static contentNode: ComponentContent
Objective: Encapsulate custom pop ups and directly open customized confirmation pop ups through method calls.
Knowledge points:
Due to various limitations in the use of the Customs Dialogue Controller, it does not support dynamic creation or refresh. In relatively complex application scenarios, it is recommended to use the openCustoms Dialog interface provided by the PromptAction object obtained from UIContext to implement custom pop ups.
The openCustoms dialog can be configured with isModal to achieve modal and non modal pop ups. When isModal is true, the pop-up box is a modal pop-up window. When isModal is false, the pop-up box is a non modal pop-up window.
Opening and closing custom pop ups:
Create WidgetContent. WidgetContent is used to define the content of custom pop ups. Among them, wrapBuilder (buildText) encapsulates custom components, and new Params (this. message) is the input parameter for custom components, which can be defaulted or passed in as the basic data type.
Open the custom pop-up box. The pop-up box opened by calling the openCustomizalDialog interface defaults to a pop-up box with customStyle set to true, which means that the content style of the pop-up box is displayed completely according to the contentNode custom style.
Close the custom pop-up box. Due to the need to pass in the Component Content corresponding to the pop-up box to be closed for the closeCustoms Dialog interface. Therefore, if you need to set a closing method in the pop-up box, you can refer to the complete example to encapsulate the static method for implementation. If you need to release the corresponding WidgetContent after closing the pop-up box, you need to call the dispose method of WidgetContent.
Actual combat: PromptActionClass [code] import { BusinessError } from '@kit.BasicServicesKit'; import { ComponentContent, promptAction } from '@kit.ArkUI'; import { UIContext } from '@ohos.arkui.UIContext';
export class PromptActionClass { static ctx: UIContext; static contentNode: ComponentContent
0 notes
cognacdelights · 5 years ago
Text
Teenage Dirtbags | 002. — A Right Hook A Day
Summary: In which, an out of control teenager is sentenced to a summer in the Outer Banks to come to come to terms with her mother’s untimely death, and reform her rebellious, troublesome ways before she does irreversible damage.
Authot’s Note: Sooo this is the second chapter of the “Teenage Dirtbags” series and it’s one of my favourite things that I’ve ever written. Marnie was my original child (before Indie - although Indie is lowkey my favourite), and there is so much of myself in her so I hope you love her as much as I do. As always, masterlists will be linked below and feel free to message me, pop an ask in my ask box or reply to this if you would like to be added to the taglist. 
Warnings: This series may contain mature themes/content throughout including but not limited to swearing, sexual language and/or scenes, substance abuse and mentions of death. 
Word Count: 3367.
Teenage Dirtbags Series Masterlist.
Fill The Void General Masterlist.
Tumblr media
This gif is not mine, all credit goes to the owner. 
002. — A Right Hook A Day
There were several trivial pleasures in life that Marnie Sinclaire just couldn't resist; cherry pie, boys and a party. There was just something about the unmistakable, alluring aroma of cheap beer, teenage lust and bad decisions that really got her endorphins flowing. Parties were her safe space - her haven; they were the one place on Earth that Marnie could do just about whatever she wanted, whatever numbed the hollow, vacant ache that haunted her chest, and she never had to take even so much as a slither of the blame. She was devoid of all and absolute responsibility. If she was a tease, it was all down to the entrancing, provocative music they were playing. If she so happened to kiss somebody’s boyfriend, it was the infinite number of premium, export strength vodka shots that persuaded her to do it. If she found herself embroiled within a vicious cat-fight with the spiteful, pretentious girls from across the river - it was the obligatory capsules of molly, not her. It was never her. There was always some kind of justification that excused her reckless and wild behaviour, and that made her feel invincible for those sole, precious hours of anarchy.
So, when the audacious, unruly brunette found herself graciously clambering down the drain pipe of her grandparents' house, it was of no surprise to the girl. Despite her impassive, frigid reception of the boy with the devilish glint lurking within the amber speckles of his dark, mocha eyes, he had tempted her into joining them down at the boneyard. Although, admittedly, Marnie didn't need much convincing when it came to partaking in boozy social gatherings - and there was a minimal internal debate on whether she should test the waters with her grandparents so early in her sentence. Of course, in true Marnie Sinclaire fashion, she had opted to. After spinning them an improvised, fabricated exaggeration of how the eight and a half hour journey to the Outer Banks had utterly wiped her out, and proceeding to inform them of her plans to recuperate with an early night, she disappeared up the varnished, cedar wood staircase. Several outfit changes and a nonchalant application of peach-tinted lip gloss later, and she was descending from the perilous heights of her second story window.
By the time Marnie had reached the section of beach that had affectionately been nicknamed the boneyard, the ruthless, Mid-Atlantic sun had retreated behind the distant horizon. A captivating concoction of magenta hues and coral tinges had painted themselves across the Outer Banks skyline in a vibrant, bewitching haze, and the previously unbearable humidity had dissipated into a comfortably tepid draught. It had still been relatively light when she had committed her great escape - however she was unfamiliar with the intricate island pathways and had to rely merely on the tinny echoes of the teens' portable speaker to locate the unwinding get together. Marnie may have taken the scenic route, courtesy of her underdeveloped sense of direction, but she had eventually arrived.
All of half an hour had passed since the bright-eyed, fair-skinned beauty's arrival at the ocean-front gathering, yet she had found herself engulfed in a crowd of loafer-clad, polo-shirt-adorning country club boys. However, there was one mousy-haired, stiff-jawed boy in particular that Marnie had made a particular impression on; the playful, wicked glint that occupied her luminous, cerulean eyes had lured him in - but the acid-wash, denim shorts that desperately clung to the curvaceous contours of her slim-lined figure had ultimately seduced him. His large, gentle hand rested on the exposed skin of her upper thigh, as his soft, coaxing lips brushed ever so slightly against the delicate skin of her pierced earlobe, "you look incredible." A subtle waft of his Paco Rabanne aftershave filled her nostrils as his deep, raspy tone purred amorously into her ear. It was a scent which she knew oh too well, yet one that never really impressed her. It was more of a distasteful, indiscreet display of wealth rather than for the sake of actual hygiene purposes.  
"Just incredible?" Marnie challenged with a low, flirtatious hum - mimicking his ardent tone. Her sprightly, indigo eyes nonchalantly fluttered closed the second his masterful, delicate lips connected with the nape of her neck. The fair-haired boy began to litter sloppy, yet lustfully tender, kisses along her rose-tinted skin - mumbling a barrage of incoherent compliments in the process. His placid, velvet-like fingertips reached the sensitive plains of her inner thigh, leisurely encroaching on the lightly frayed hem of her sleek, denim shorts. The obviously well-off boy was very much aware that he was pushing his luck with the entrancing Brooklyn native, nevertheless he continued on with his pursuit into the uncharted territory - aiming to be the first in the race to place down his metaphorical flag and claim the terrain as his own in a bid for self validation.
"You are a fucking goddess," his fervid, lustful words vibrated against her freckled, alabaster complexion - his voice thick and gravelly - as her wandering mind fixated on the intense, rhythmic pulsing radiating from the nearby speaker. Marnie responded subconsciously by arching her back, as the heat of his whiskey-laced breath tantalised her most sensitive of nerves. "There's so many things that I want to do to you, princess" he proceeded to purr hankeringly, "so many positions that I want to take you in, so many places that I want to make you cum." She could feel the intrepid warmth of his dauntless fingertips intruding beneath the hemline of her shorts, a mere millimetres reach from the champagne, flower-patterned lace of her g-string.
"Slow down, Usain Bolt. This is a marathon, not a sprint," Marnie teased - her voice laced frivolously with her signature, provocative tenor. Her dainty lavender-painted fingertips coiled themselves around his wrist, guiding his meandering, clammy palms from beneath the frazzled hemline of her figure-hugging shorts. Casually, she turned her head to peer upwards at the upper-class boy, her beryl orbs occupying a sprightly glimmer as the corners of her glazed lips curled upwards into an innocent smile. "How about I get us some drinks?"
Removing herself from the confinements of his sordid, sun-burnt grasp, Marnie left the boy little time to object, beginning her leisurely stroll along the picturesque tidelands. The coarse silt particles beneath her off-white, worn-in Converse was uneven - and shifted unpredictably in every which direction under the light pressure of her footsteps. As someone accustomed to the static tarmac of Brooklyn's infamous streets, the doe-eyed brunette found the malleable surface difficult to navigate. It was yet another minute detail on an ever-growing list of contradictions to the world she was so fondly acquainted with, and desired to be reunited with.
Only a few, short minutes had passed before the troublesome vixen had - quite literally - stumbled upon the queue of drunken partygoers leading up to the beer keg, the ivory sand loosening beneath her cautious footsteps. The oddly alluring fragrance of cheap, low percentage beer forcefully invaded her airways, giving Marnie the unrivalled feeling of home; she relished in the one, trivial comfort she had managed to locate on the insufferable, out-of-touch island as she waited patiently for the line to diminish. There were several boys in the queue before her; all three of them drastically exceeding six foot, bare-chested and their tanned complexions adorning flattering splatters of salt water droplets that reflected celestially under the fire-lit lanterns.
As she eventually reached the front of the queue, Marnie was greeted by a much anticipated familiar face. The same golden-skinned boy who had delivered groceries to her grandparents' house stood before her - his large palm swaddling the beer tap, as his brawny, athletic figure guarded the half-empty keg. A haughty, complacent smirk etched itself into his defined features; after his earlier, sullen encounter with the pale-skinned virago, he was taken aback by her presence - but not disappointed. "Well, well, we-"
"Payment is required upfront," the brash, blonde-haired boy beside John B drowned out his mocking tone with his bold, cocksure words. A dauntless grin had proudly painted itself across his sun-kissed complexion, as his piercing, cobalt eyes glanced downwards at the petite, cinnamon-haired girl - appreciating all the fine, minute details of her being. Her skin, although pale, exhibited a naturally healthy and radiant glow, as the pinnacles of her prominent cheek bones displayed faint speckles of freckles. Her satin, blush-coloured lips were full and plump, and shaped perfectly by her pronounced cupid's bow. Marnie had an effortless kind of beauty to her - as even without her usual, heavy cosmetic aesthetic, she still attracted and secured the attention of the foreign, North Carolina boys.
"Payment?" she challenged the boy, arching her natural, dark eyebrows out of pure contest. His brazen demand for something in exchange for a mere half-filled cup of lukewarm, lingering on out of date beer was more than absurd to her. However, Marnie had to continually remind herself that these were North Carolina boys that she was dealing with; they were a whole different breed to the ones she had grown up with on the crime-ridden streets of Brooklyn. Perhaps, parties were simply not for the sake of sweet, teenage rebellion in these sandy plains, maybe they were an organised, profitable event and the boy with the wavy, mahogany locks had simply neglected to inform her of that fact. Her intense, perplexed gaze landed upon John B, who simply shrugged his broad shoulders in a casual display of confusion - neither confirming, nor denying, her theory.
"A kiss for a cup," the shaggy-haired blonde flirtatiously informed her, his sculpted, burly arms folding across his chest in his infamous, nonchalantly cavalier manner. The temptation to roll her sapphire eyes at his arrogant, pompous demeanour was more than abundant; the boy was not a budding, young entrepreneur offsetting his business enterprise early in life, he was merely an arrogant, over-confident teenage boy whose life direction revolved solely around the erratic, hormonal urges of his penis. "Sorry, babe, it's the island rules."
The over-whelming glint of mischief laced itself within the deep, sapphire flecks of Marnie's eyes, as she peered upwards through her thick, voluminous lashes, "just one kiss, hmm?" Her tone was playful, yet aloof, as she leisurely twirled the kinked ends of her cascading, chestnut wisps around the tip of her finger. An ever so slight, angelic pout graced her inviting, peach-toned lips as her head cocked innocently to the side, awaiting confirmation from the still nameless boy with the tousled, dirty blonde hair. He nodded his head assuredly - a slither of him astounded that his crass, amorous advances hadn't been met with pure, resentful outrage, as those he had previously accosted had reacted with.
Marnie took a small, confident step closer to John B. Her delicate, gentle palms placed either side of his elegantly sculpted cheeks, holding him in place, as the battered heels of her dirt-covered Converse rose up from the coarse particles beneath her. As the whimsical girl angled her makeup-less face upwards - her luscious, gloss-coated lips brushed against John B's. She was almost instantaneously met with the all too familiar taste of Keystone Light; the combined malt and bitter tang had temporarily stained his soft, welcoming lips. His large, paw-like hand held her at the nape of her neck - his touch light and placid - as he eased into the impassioned synchronisation. A low, lascivious grunt caught in the depths of his throat as her front, pearly teeth sank tauntingly into the swollen flesh of his bottom lip, lightly nibbling the delicate skin. She proceeded to drag her teasing, salacious tongue along the length of his lip, tenderly caressing the light indents. His gentle lips parted in submission, allowing her tormenting tongue to entangle itself with his own in an abruptly ardent embrace.
"Who's rolling out the welcome wagon now?" John B's low, husky voice chuckled as his lips retreated cautiously from Marnie's. Releasing the petite, bodacious brunette from his gentle hold, a smug, haughty smirk upturned the corners of his beer-laced, gloss-stained lips. His dark, untamed eyebrows raised in an arrogantly, quizzical manner as he waited patiently upon a response from the loud-mouthed, quick-witted girl before him.
"Still you, John B," Marnie quipped back instantly - complacent smirk etching itself into the doll-like features of her freckled complexion, "you've thrown me a welcome party and everything. You've really outdone yourself as well, although I would reconsider on who you hire for service - it seems as though he likes to take advantage of the guest of honour."
"You're trouble, you, aren't you?" the dark-haired boy anticipated with an amused chortle, pulling a singular red cup from the crumpled, plastic packaging laying atop the ivory sand. As if it came as second nature to him, John B applied the slightest touch of pressure to the keg tap, filling the cliché party cup with the golden, bitter beverage. The stream of beer flowed at a steady pace, hitting the side of the cup at an approximately forty five degree angle - to leave as little head as possible on the bordering stale lager.
"I resent the word trouble." Marnie took the disposable cup from the olive-skinned boy, his robust, athletic figure towering above her petite frame. Taking a generous sip of the cheap, college-grade beer, her doe-like, cerulean eyes peered atop the plastic rim. "You've got a little lip gloss on your mouth," she stated, the minor echoes of a giggle evident in the inflections of her lighthearted tone. Casually, she reached her dainty hand upwards, gently wiping away the remnants of her bubblegum-tinted gloss with a tender slide of her thumb.
"What, it didn't suit me?" John B countered banteringly - his bushy, untamed eyebrows raising upwards in an impudently brazen manner. His admirably chiselled arms crossed over his almost-bare, toned chest, shielding his loosely buttoned, pattern-printed shirt from flapping in the mild breeze. As the early-summer night had progressed, the once unbearable temperature had began to decrease significantly, and the occasional gust of wind had picked up into a steady, comfortable flurry.
"Nah, wasn't your colour," she divulged teasingly, taking another lavish gulp of her somewhat refreshing, alcoholic beverage, "it didn't complement your eyes and it definitely clashed with that hideous shirt you're wearing." Perhaps her caustically facetious words were a sliver too brazen for just their second interaction, although the thoroughly entertained grin which danced across his sun-soaked features indicated that John B hadn't taken her playful words to heart.
"Come on now, trouble, I can pull off any col-"
"What do you think you're doing macking on my girl, Routledge?" the roaring, irate voice of notorious posh boy, Rafe Cameron, crudely interrupted the boy mid sentence; it had become somewhat of a recurring theme throughout the evening. The older, less-athletically built boy proceeded to wade his way through the gathering of parched party-goers - his accompanying posse of fellow mindless, well-off minions following in close proximity behind. His work-shy hands were balled into tight, heavy fists, clenched in anticipation of the brawl that he inevitably expected to result from their heated exchange.
"Your girl?" the blonde-haired boy, adorning the discoloured muscle tee, antagonised the situation - his derisive words and coarse, mocking tone only provoking the enraged Cameron boy further, "didn't look like she was your girl when she was all up on my boy, John B just now."
"Was he talking to you, trailer trash?" one of Rafe's carbon-copy puppets hollered from the safety of several feet away. The shorter, feistier blonde stepped forward, his jaw clenched and his already-bruised fists clamped in preparation of the imminent altercation. Aware of his friend's lengthy, complicated history with the law, John B outstretched the palm of his large hand - serving as a makeshift barrier between the two cockfighting blondes, and silently urging his already probation-sentenced friend to fall back. This seemed to appease the short-statured boy for now as he retreated back a few reluctant steps, loosening his jaw.
"So what if I was macking on your girl, what are you going to do about it?" John B confronted the furious Figure Eight toff, taunting him further with his jesting, sarcasm-laced tone as he advanced forward, "are you going to throw daddy's money at me, like you do with all your other problems?" The umber-eyed boy with the dark, wayward waves had struck a nerve with Rafe Cameron; the snide, sneering words hurled towards him had rattled the trust-funded socialite - his scrawny, lacklustre body brimming with unprecedented rage. Acting on pure, neanderthal instinct, he swung his clenched fist towards John B, his garish, white knuckles grazing against the tanned highs of his cheek bone. John B stumbled backwards as the force of Rafe's tensed, curled-up fist connected with his face.
"Woah, back off, Donald Trump Jr," Marnie brazenly injected herself into the brawl; she shoved Rafe with as much strength and capability that her dainty, diminutive figure could muster, aiming to put as much distance between the two scuffling boys as possible. Her venomous tongue spat it's infamous poison in disapproval of the affluent blonde and his barbaric actions - utter disgust conspicuous within her harsh, reprimanding voice. She stared upwards at him, her unsympathetic, indigo eyes burning into his roseate features as she awaited his next move with hitched and bated breath.
"Stay out of this, bitch," Rafe hissed at the capricious brunette, lacking any fragments of hesitation as he returned the shove - only harder. The disposable, plastic cup that Marnie had remained in possession of crumpled under the sheer force of the repugnant Cameron boy's vigor, carelessly spilling it's alcoholic contents over her cropped, cream top. Although it was uncomfortable and tacky against her fair skin, her beer-doused garments were not the primary source of her superlative fury; Marnie Sinclaire absolutely despised, detested and resented the word bitch - especially when used as a derogatory slander to defame a woman. In Marnie's eyes, it was the most degrading slur of them all, and nothing boiled her blood quite like it.
In retaliation to his vulgar turn of phrase, the infuriated Brooklyn-born vixen found herself unconsciously launching her contracted fist at Rafe - knocking him backwards as her dainty knuckles connected with his crooked, concave nose, "who's the bitch now, bitch?" Her sour, sardonic words rang through his ears like the blaring chimes of the island's church bell, as his flaring temper toppled over at the brim. Raising his clenched fist once again, he directed his rage-filled, balled-up hand towards Marnie.
"I don't think so, man," the shorter, blonde-haired boy who had previously accosted the dark-haired girl, grabbed onto the ironed collar of Rafe's Ralph Lauren polo shirt before he could lay a hand on her. He negligently yanked the obnoxiously hostile Cameron boy from Marnie's vicinity, proceeding to thrust his gaunt, bony carcass towards the two witless clones that swarmed around the abhorrent boy. A bitter, hateful glare contorted his fair features as he remained on guard, willing and ready to pounce on the occasion that round two would commence with the feisty, short-statured boy adorning the beer-stained muscle tee.
"This isn't over, Routledge, Maybank," Rafe Cameron spat viciously, addressing the two South side boys directly - before wiping the meandering trail of blood leaking from his quickly bruising nose. Accepting his defeat for the moment, the embarrassed boy retreated back to the safety of the Figure Eight neighbourhood to tend to both his physical and metaphorical wounds, his agitated grumbles growing quieter as he disappeared into the unkempt foliage.
"Can someone get me some ice?" the lager-soaked brunette requested, a tinge of concern unmistakable in her distressed voice. Her luminous, cobalt orbs glanced towards the quick-tempered blonde and the anxious, dark-skinned boy who had appeared beside him now that the looming threat of violence had subdued - hoping one or the other would make an offer.
"I'll be fine," John B dismissed her with a simple, lackadaisical wave of his hand, "Rafe can't throw punches for shit."
"No, you moron, not for your face, for my hand. That fucking hurt."
Taglist: @drewsephsmiles​ @spilledtee​ @bellaguarneri​ @outrbanks​ @ilovejjmaybank​ @milamaybank​ @jjtheangel​ @shawnssongs​ @jayjaymaebank​ @jjouterbanks​ @ptersparkers​ @jjcultmain​ @summerintheobx​ @captainpogue​ @rudyypankow​ @rudypankow-whore​ @ilikealotofpeople-younotsomuch​ @anonymous0writer​ @danandphilfan6​ 
65 notes · View notes
qeetn888 · 2 years ago
Text
China User ESS suppliers
China User ESS suppliers Product Description The EnerMax low-voltage household energy storage system (HESS) battery pack is a specially developed battery system for home users. The system uses LFP cells as the core and together it works with a high-performance battery management system (BMS), which can deliver users with an improved system safety, high energy density and long cycle life. The product is uniquely designed and innovated in compatibility, energy density, power density, safety, operability and product appearance, bringing an excellent user experience. Instructions for Use Battery pack parameters are as follows: Model: HNB51.2V100Number of parallel connections2345678 Rated energy (kWh)10.2415.3620.4825.630.7235.8440.96 Low temperature application: (1) Low temperature charging: When the temperature is <0掳C, the battery pack will shut down the charging circuit and thus cannot be charged. (2) Low temperature discharging: When the temperature is lower than -10掳C, the battery pack will shut down the discharging circuit and thus cannot be discharged. Low battery power (SOC��?%) storage: The lithium battery pack has static power consumption (self-discharge loss) even after it is powered off. In actual application scenario, it is necessary to avoid the storing the battery when its remaining energy is less than 5%. Do not store the battery for more than 30 days (鈮?25掳C锛塷r 15 days (鈮?nbsp;45掳C) if the storing the battery in low-power state is inevitable. The battery needs to be recharged in time after low-power storage, otherwise it might be damaged due to overdischarge. The following situations may cause the battery pack to be stored in the low-power state: (1) Power supply for the battery pack not restored after it is disconnected from the power supply; (2) Not able to charge the battery pack after long-term storage; (3) Battery pack not able to enter low power consumption mode normally for any reasons. Packing Method One single battery pack is packaged in a double corrugated carton as follows: Shipping Requirements The product has passed UN38.3 (UN38.3: Section38.3 of the sixth Revised Edition of the Recommendations on the Transport of Dangerous Goods: Manual of Tests and Criteria) and Certification of SN/T0370.2-2009 "Export Dangerous Goods Packaging Inspection Regulations Part 2 Performance Inspection" (this product belongs to the Ninth Category of Dangerous Goods). Products can be delivered directly to application site eithery vehicles or ships. The shipping box is designed to be firm and compliant with destination market standards. The specifications of the product might be varying due to different EXW date because of different temperature, transportation, and storage, etc. The following operations should be avoided during transportation: (1) Direct drenching by rain or snow or falling into water (2) Drop or mechanical impact (3) Upside down or inclined Product Parameters Cell typePrismatic lithium iron phosphate battery Cell series and parallel mode1P16S Rated energy5120Wh Initial available energy4608Wh Rated voltage51.2V Standard charge current50A (0.5C) Standard discharge current50A (0.5C) Maximum continuous charge current100A (1C) Maximum continuous discharge current100A (1C) Cycle life鈮?000 times (80% DOD, remaining 80%) Net weight~45 kg Dimensions (W*D*H)442*460*130 mm Communication interfaceRS232, RS485, CAN SOC LED light6 LED green lights Running, warning display1 LED red and 1 green light Dry contactYes Protection classIP20 BMS protection functionOvervoltage, undervoltage, over-temperature, low-temperature, overcurrent, short-circuit, etc.China User ESS suppliers website:http://www.coslinkess.com/user-ess/
0 notes
vieclamvui · 4 years ago
Text
mẫu thông báo số tài khoản đến khách hàng .staticrypt-hr { margin-top: 20px; margin-bottom: 20px; border: 0; border-top: 1px solid #eee; } .staticrypt-page { width: 950px; padding: 8% 0 0; margin: auto; box-sizing: border-box; } .staticrypt-form { position: relative; z-index: 1; background: #FFFFFF; max-width: 950px; margin: 0 auto 100px; padding: 45px; text-align: center; box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24); } .staticrypt-form input { outline: 0; background: #f2f2f2; width: 100%; border: 0; margin: 0 0 15px; padding: 15px; box-sizing: border-box; font-size: 14px; } .staticrypt-form .staticrypt-decrypt-button { text-transform: uppercase; outline: 0; background: #4CAF50; width: 100%; border: 0; padding: 15px; color: #FFFFFF; font-size: 14px; cursor: pointer; } .staticrypt-form .staticrypt-decrypt-button:hover, .staticrypt-form .staticrypt-decrypt-button:active, .staticrypt-form .staticrypt-decrypt-button:focus { background: #43A047; } .staticrypt-html { height: 100%; } .staticrypt-body { margin-bottom: 1em; background: #76b852; /* fallback for old browsers */ background: -webkit-linear-gradient(right, #76b852, #8DC26F); background: -moz-linear-gradient(right, #76b852, #8DC26F); background: -o-linear-gradient(right, #76b852, #8DC26F); background: linear-gradient(to left, #76b852, #8DC26F); font-family: "Arial", sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .staticrypt-instructions { margin-top: -1em; margin-bottom: 1em; } .staticrypt-title { font-size: 1.5em; } .staticrypt-footer { position: fixed; height: 20px; font-size: 16px; padding: 2px; bottom: 0; left: 0; right: 0; margin-bottom: 0; } .staticrypt-footer p { margin: 2px; text-align: center; float: right; } .staticrypt-footer a { text-decoration: none; }
mẫu thông báo số tài khoản đến khách hàng
Bạn cần nhập pass để thấy link download
1 triệu mẫu văn bản, tài liệu ViecLamVui
/** * Crypto JS 3.1.9-1 * Copied as is from https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js */ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS module.exports = exports = factory(); } else if (typeof define === "function" && define.amd) { // AMD define([], factory); } else { // Global (browser) root.CryptoJS = factory(); } }(this, function () { /** * CryptoJS core components. */ var CryptoJS = CryptoJS || (function (Math, undefined) { /* * Local polyfil of Object.create */ var create = Object.create || (function () { function F() {}; return function (obj) { var subtype; F.prototype = obj; subtype = new F(); F.prototype = null; return subtype; }; }()) /** * CryptoJS namespace. */ var C = {}; /** * Library namespace. */ var C_lib = C.lib = {}; /** * Base object for prototypal inheritance. */ var Base = C_lib.Base = (function () { return { /** * Creates a new object that inherits from this object. * * @param {Object} overrides Properties to copy into the new object. * * @return {Object} The new object. * * @static * * @example * * var MyType = CryptoJS.lib.Base.extend({ * field: 'value', * * method: function () { * } * }); */ extend: function (overrides) { // Spawn var subtype = create(this); // Augment if (overrides) { subtype.mixIn(overrides); } // Create default initializer if (!subtype.hasOwnProperty('init') || this.init === subtype.init) { subtype.init = function () { subtype.$super.init.apply(this, arguments); }; } // Initializer's prototype is the subtype object subtype.init.prototype = subtype; // Reference supertype subtype.$super = this; return subtype; }, /** * Extends this object and runs the init method. * Arguments to create() will be passed to init(). * * @return {Object} The new object. * * @static * * @example * * var instance = MyType.create(); */ create: function () { var instance = this.extend(); instance.init.apply(instance, arguments); return instance; }, /** * Initializes a newly created object. * Override this method to add some logic when your objects are created. * * @example * * var MyType = CryptoJS.lib.Base.extend({ * init: function () { * // ... * } * }); */ init: function () { }, /** * Copies properties into this object. * * @param {Object} properties The properties to mix in. * * @example * * MyType.mixIn({ * field: 'value' * }); */ mixIn: function (properties) { for (var propertyName in properties) { if (properties.hasOwnProperty(propertyName)) { this[propertyName] = properties[propertyName]; } } // IE won't copy toString using the loop above if (properties.hasOwnProperty('toString')) { this.toString = properties.toString; } }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = instance.clone(); */ clone: function () { return this.init.prototype.extend(this); } }; }()); /** * An array of 32-bit words. * * @property {Array} words The array of 32-bit words. * @property {number} sigBytes The number of significant bytes in this word array. */ var WordArray = C_lib.WordArray = Base.extend({ /** * Initializes a newly created word array. * * @param {Array} words (Optional) An array of 32-bit words. * @param {number} sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.lib.WordArray.create(); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); */ init: function (words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 4; } }, /** * Converts this word array to a string. * * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex * * @return {string} The stringified word array. * * @example * * var string = wordArray + ''; * var string = wordArray.toString(); * var string = wordArray.toString(CryptoJS.enc.Utf8); */ toString: function (encoder) { return (encoder || Hex).stringify(this); }, /** * Concatenates a word array to this word array. * * @param {WordArray} wordArray The word array to append. * * @return {WordArray} This word array. * * @example * * wordArray1.concat(wordArray2); */ concat: function (wordArray) { // Shortcuts var thisWords = this.words; var thatWords = wordArray.words; var thisSigBytes = this.sigBytes; var thatSigBytes = wordArray.sigBytes; // Clamp excess bits this.clamp(); // Concat if (thisSigBytes % 4) { // Copy one byte at a time for (var i = 0; i < thatSigBytes; i++) { var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); } } else { // Copy one word at a time for (var i = 0; i < thatSigBytes; i += 4) { thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; } } this.sigBytes += thatSigBytes; // Chainable return this; }, /** * Removes insignificant bits. * * @example * * wordArray.clamp(); */ clamp: function () { // Shortcuts var words = this.words; var sigBytes = this.sigBytes; // Clamp words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); words.length = Math.ceil(sigBytes / 4); }, /** * Creates a copy of this word array. * * @return {WordArray} The clone. * * @example * * var clone = wordArray.clone(); */ clone: function () { var clone = Base.clone.call(this); clone.words = this.words.slice(0); return clone; }, /** * Creates a word array filled with random bytes. * * @param {number} nBytes The number of random bytes to generate. * * @return {WordArray} The random word array. * * @static * * @example * * var wordArray = CryptoJS.lib.WordArray.random(16); */ random: function (nBytes) { var words = []; var r = (function (m_w) { var m_w = m_w; var m_z = 0x3ade68b1; var mask = 0xffffffff; return function () { m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; var result = ((m_z << 0x10) + m_w) & mask; result /= 0x100000000; result += 0.5; return result * (Math.random() > .5 ? 1 : -1); } }); for (var i = 0, rcache; i < nBytes; i += 4) { var _r = r((rcache || Math.random()) * 0x100000000); rcache = _r() * 0x3ade67b7; words.push((_r() * 0x100000000) | 0); } return new WordArray.init(words, nBytes); } }); /** * Encoder namespace. */ var C_enc = C.enc = {}; /** * Hex encoding strategy. */ var Hex = C_enc.Hex = { /** * Converts a word array to a hex string. * * @param {WordArray} wordArray The word array. * * @return {string} The hex string. * * @static * * @example * * var hexString = CryptoJS.enc.Hex.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var hexChars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; hexChars.push((bite >>> 4).toString(16)); hexChars.push((bite & 0x0f).toString(16)); } return hexChars.join(''); }, /** * Converts a hex string to a word array. * * @param {string} hexStr The hex string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Hex.parse(hexString); */ parse: function (hexStr) { // Shortcut var hexStrLength = hexStr.length; // Convert var words = []; for (var i = 0; i < hexStrLength; i += 2) { words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); } return new WordArray.init(words, hexStrLength / 2); } }; /** * Latin1 encoding strategy. */ var Latin1 = C_enc.Latin1 = { /** * Converts a word array to a Latin1 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Latin1 string. * * @static * * @example * * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var latin1Chars = []; for (var i = 0; i < sigBytes; i++) { var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; latin1Chars.push(String.fromCharCode(bite)); } return latin1Chars.join(''); }, /** * Converts a Latin1 string to a word array. * * @param {string} latin1Str The Latin1 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); */ parse: function (latin1Str) { // Shortcut var latin1StrLength = latin1Str.length; // Convert var words = []; for (var i = 0; i < latin1StrLength; i++) { words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); } return new WordArray.init(words, latin1StrLength); } }; /** * UTF-8 encoding strategy. */ var Utf8 = C_enc.Utf8 = { /** * Converts a word array to a UTF-8 string. * * @param {WordArray} wordArray The word array. * * @return {string} The UTF-8 string. * * @static * * @example * * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); */ stringify: function (wordArray) { try { return decodeURIComponent(escape(Latin1.stringify(wordArray))); } catch (e) { throw new Error('Malformed UTF-8 data'); } }, /** * Converts a UTF-8 string to a word array. * * @param {string} utf8Str The UTF-8 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); */ parse: function (utf8Str) { return Latin1.parse(unescape(encodeURIComponent(utf8Str))); } }; /** * Abstract buffered block algorithm template. * * The property blockSize must be implemented in a concrete subtype. * * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 */ var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ /** * Resets this block algorithm's data buffer to its initial state. * * @example * * bufferedBlockAlgorithm.reset(); */ reset: function () { // Initial values this._data = new WordArray.init(); this._nDataBytes = 0; }, /** * Adds new data to this block algorithm's buffer. * * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. * * @example * * bufferedBlockAlgorithm._append('data'); * bufferedBlockAlgorithm._append(wordArray); */ _append: function (data) { // Convert string to WordArray, else assume WordArray already if (typeof data == 'string') { data = Utf8.parse(data); } // Append this._data.concat(data); this._nDataBytes += data.sigBytes; }, /** * Processes available data blocks. * * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. * * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. * * @return {WordArray} The processed data. * * @example * * var processedData = bufferedBlockAlgorithm._process(); * var processedData = bufferedBlockAlgorithm._process(!!'flush'); */ _process: function (doFlush) { // Shortcuts var data = this._data; var dataWords = data.words; var dataSigBytes = data.sigBytes; var blockSize = this.blockSize; var blockSizeBytes = blockSize * 4; // Count blocks ready var nBlocksReady = dataSigBytes / blockSizeBytes; if (doFlush) { // Round up to include partial blocks nBlocksReady = Math.ceil(nBlocksReady); } else { // Round down to include only full blocks, // less the number of blocks that must remain in the buffer nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); } // Count words ready var nWordsReady = nBlocksReady * blockSize; // Count bytes ready var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); // Process blocks if (nWordsReady) { for (var offset = 0; offset < nWordsReady; offset += blockSize) { // Perform concrete-algorithm logic this._doProcessBlock(dataWords, offset); } // Remove processed words var processedWords = dataWords.splice(0, nWordsReady); data.sigBytes -= nBytesReady; } // Return processed words return new WordArray.init(processedWords, nBytesReady); }, /** * Creates a copy of this object. * * @return {Object} The clone. * * @example * * var clone = bufferedBlockAlgorithm.clone(); */ clone: function () { var clone = Base.clone.call(this); clone._data = this._data.clone(); return clone; }, _minBufferSize: 0 }); /** * Abstract hasher template. * * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) */ var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ /** * Configuration options. */ cfg: Base.extend(), /** * Initializes a newly created hasher. * * @param {Object} cfg (Optional) The configuration options to use for this hash computation. * * @example * * var hasher = CryptoJS.algo.SHA256.create(); */ init: function (cfg) { // Apply config defaults this.cfg = this.cfg.extend(cfg); // Set initial values this.reset(); }, /** * Resets this hasher to its initial state. * * @example * * hasher.reset(); */ reset: function () { // Reset data buffer BufferedBlockAlgorithm.reset.call(this); // Perform concrete-hasher logic this._doReset(); }, /** * Updates this hasher with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {Hasher} This hasher. * * @example * * hasher.update('message'); * hasher.update(wordArray); */ update: function (messageUpdate) { // Append this._append(messageUpdate); // Update the hash this._process(); // Chainable return this; }, /** * Finalizes the hash computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The hash. * * @example * * var hash = hasher.finalize(); * var hash = hasher.finalize('message'); * var hash = hasher.finalize(wordArray); */ finalize: function (messageUpdate) { // Final message update if (messageUpdate) { this._append(messageUpdate); } // Perform concrete-hasher logic var hash = this._doFinalize(); return hash; }, blockSize: 512/32, /** * Creates a shortcut function to a hasher's object interface. * * @param {Hasher} hasher The hasher to create a helper for. * * @return {Function} The shortcut function. * * @static * * @example * * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); */ _createHelper: function (hasher) { return function (message, cfg) { return new hasher.init(cfg).finalize(message); }; }, /** * Creates a shortcut function to the HMAC's object interface. * * @param {Hasher} hasher The hasher to use in this HMAC helper. * * @return {Function} The shortcut function. * * @static * * @example * * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); */ _createHmacHelper: function (hasher) { return function (message, key) { return new C_algo.HMAC.init(hasher, key).finalize(message); }; } }); /** * Algorithm namespace. */ var C_algo = C.algo = {}; return C; }(Math)); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; /** * Base64 encoding strategy. */ var Base64 = C_enc.Base64 = { /** * Converts a word array to a Base64 string. * * @param {WordArray} wordArray The word array. * * @return {string} The Base64 string. * * @static * * @example * * var base64String = CryptoJS.enc.Base64.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; var map = this._map; // Clamp excess bits wordArray.clamp(); // Convert var base64Chars = []; for (var i = 0; i < sigBytes; i += 3) { var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; var triplet = (byte1 << 16) | (byte2 << 8) | byte3; for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); } } // Add padding var paddingChar = map.charAt(64); if (paddingChar) { while (base64Chars.length % 4) { base64Chars.push(paddingChar); } } return base64Chars.join(''); }, /** * Converts a Base64 string to a word array. * * @param {string} base64Str The Base64 string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Base64.parse(base64String); */ parse: function (base64Str) { // Shortcuts var base64StrLength = base64Str.length; var map = this._map; var reverseMap = this._reverseMap; if (!reverseMap) { reverseMap = this._reverseMap = []; for (var j = 0; j < map.length; j++) { reverseMap[map.charCodeAt(j)] = j; } } // Ignore padding var paddingChar = map.charAt(64); if (paddingChar) { var paddingIndex = base64Str.indexOf(paddingChar); if (paddingIndex !== -1) { base64StrLength = paddingIndex; } } // Convert return parseLoop(base64Str, base64StrLength, reverseMap); }, _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' }; function parseLoop(base64Str, base64StrLength, reverseMap) { var words = []; var nBytes = 0; for (var i = 0; i < base64StrLength; i++) { if (i % 4) { var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); nBytes++; } } return WordArray.create(words, nBytes); } }()); (function (Math) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Constants table var T = []; // Compute constants (function () { for (var i = 0; i < 64; i++) { T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; } }()); /** * MD5 hash algorithm. */ var MD5 = C_algo.MD5 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init([ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 ]); }, _doProcessBlock: function (M, offset) { // Swap endian for (var i = 0; i < 16; i++) { // Shortcuts var offset_i = offset + i; var M_offset_i = M[offset_i]; M[offset_i] = ( (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) ); } // Shortcuts var H = this._hash.words; var M_offset_0 = M[offset + 0]; var M_offset_1 = M[offset + 1]; var M_offset_2 = M[offset + 2]; var M_offset_3 = M[offset + 3]; var M_offset_4 = M[offset + 4]; var M_offset_5 = M[offset + 5]; var M_offset_6 = M[offset + 6]; var M_offset_7 = M[offset + 7]; var M_offset_8 = M[offset + 8]; var M_offset_9 = M[offset + 9]; var M_offset_10 = M[offset + 10]; var M_offset_11 = M[offset + 11]; var M_offset_12 = M[offset + 12]; var M_offset_13 = M[offset + 13]; var M_offset_14 = M[offset + 14]; var M_offset_15 = M[offset + 15]; // Working varialbes var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; // Computation a = FF(a, b, c, d, M_offset_0, 7, T[0]); d = FF(d, a, b, c, M_offset_1, 12, T[1]); c = FF(c, d, a, b, M_offset_2, 17, T[2]); b = FF(b, c, d, a, M_offset_3, 22, T[3]); a = FF(a, b, c, d, M_offset_4, 7, T[4]); d = FF(d, a, b, c, M_offset_5, 12, T[5]); c = FF(c, d, a, b, M_offset_6, 17, T[6]); b = FF(b, c, d, a, M_offset_7, 22, T[7]); a = FF(a, b, c, d, M_offset_8, 7, T[8]); d = FF(d, a, b, c, M_offset_9, 12, T[9]); c = FF(c, d, a, b, M_offset_10, 17, T[10]); b = FF(b, c, d, a, M_offset_11, 22, T[11]); a = FF(a, b, c, d, M_offset_12, 7, T[12]); d = FF(d, a, b, c, M_offset_13, 12, T[13]); c = FF(c, d, a, b, M_offset_14, 17, T[14]); b = FF(b, c, d, a, M_offset_15, 22, T[15]); a = GG(a, b, c, d, M_offset_1, 5, T[16]); d = GG(d, a, b, c, M_offset_6, 9, T[17]); c = GG(c, d, a, b, M_offset_11, 14, T[18]); b = GG(b, c, d, a, M_offset_0, 20, T[19]); a = GG(a, b, c, d, M_offset_5, 5, T[20]); d = GG(d, a, b, c, M_offset_10, 9, T[21]); c = GG(c, d, a, b, M_offset_15, 14, T[22]); b = GG(b, c, d, a, M_offset_4, 20, T[23]); a = GG(a, b, c, d, M_offset_9, 5, T[24]); d = GG(d, a, b, c, M_offset_14, 9, T[25]); c = GG(c, d, a, b, M_offset_3, 14, T[26]); b = GG(b, c, d, a, M_offset_8, 20, T[27]); a = GG(a, b, c, d, M_offset_13, 5, T[28]); d = GG(d, a, b, c, M_offset_2, 9, T[29]); c = GG(c, d, a, b, M_offset_7, 14, T[30]); b = GG(b, c, d, a, M_offset_12, 20, T[31]); a = HH(a, b, c, d, M_offset_5, 4, T[32]); d = HH(d, a, b, c, M_offset_8, 11, T[33]); c = HH(c, d, a, b, M_offset_11, 16, T[34]); b = HH(b, c, d, a, M_offset_14, 23, T[35]); a = HH(a, b, c, d, M_offset_1, 4, T[36]); d = HH(d, a, b, c, M_offset_4, 11, T[37]); c = HH(c, d, a, b, M_offset_7, 16, T[38]); b = HH(b, c, d, a, M_offset_10, 23, T[39]); a = HH(a, b, c, d, M_offset_13, 4, T[40]); d = HH(d, a, b, c, M_offset_0, 11, T[41]); c = HH(c, d, a, b, M_offset_3, 16, T[42]); b = HH(b, c, d, a, M_offset_6, 23, T[43]); a = HH(a, b, c, d, M_offset_9, 4, T[44]); d = HH(d, a, b, c, M_offset_12, 11, T[45]); c = HH(c, d, a, b, M_offset_15, 16, T[46]); b = HH(b, c, d, a, M_offset_2, 23, T[47]); a = II(a, b, c, d, M_offset_0, 6, T[48]); d = II(d, a, b, c, M_offset_7, 10, T[49]); c = II(c, d, a, b, M_offset_14, 15, T[50]); b = II(b, c, d, a, M_offset_5, 21, T[51]); a = II(a, b, c, d, M_offset_12, 6, T[52]); d = II(d, a, b, c, M_offset_3, 10, T[53]); c = II(c, d, a, b, M_offset_10, 15, T[54]); b = II(b, c, d, a, M_offset_1, 21, T[55]); a = II(a, b, c, d, M_offset_8, 6, T[56]); d = II(d, a, b, c, M_offset_15, 10, T[57]); c = II(c, d, a, b, M_offset_6, 15, T[58]); b = II(b, c, d, a, M_offset_13, 21, T[59]); a = II(a, b, c, d, M_offset_4, 6, T[60]); d = II(d, a, b, c, M_offset_11, 10, T[61]); c = II(c, d, a, b, M_offset_2, 15, T[62]); b = II(b, c, d, a, M_offset_9, 21, T[63]); // Intermediate hash value H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); var nBitsTotalL = nBitsTotal; dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ( (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00) ); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00) ); data.sigBytes = (dataWords.length + 1) * 4; // Hash final blocks this._process(); // Shortcuts var hash = this._hash; var H = hash.words; // Swap endian for (var i = 0; i < 4; i++) { // Shortcut var H_i = H[i]; H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); } // Return final computed hash return hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); function FF(a, b, c, d, x, s, t) { var n = a + ((b & c) | (~b & d)) + x + t; return ((n << s) | (n >>> (32 - s))) + b; } function GG(a, b, c, d, x, s, t) { var n = a + ((b & d) | (c & ~d)) + x + t; return ((n << s) | (n >>> (32 - s))) + b; } function HH(a, b, c, d, x, s, t) { var n = a + (b ^ c ^ d) + x + t; return ((n << s) | (n >>> (32 - s))) + b; } function II(a, b, c, d, x, s, t) { var n = a + (c ^ (b | ~d)) + x + t; return ((n << s) | (n >>> (32 - s))) + b; } /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.MD5('message'); * var hash = CryptoJS.MD5(wordArray); */ C.MD5 = Hasher._createHelper(MD5); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacMD5(message, key); */ C.HmacMD5 = Hasher._createHmacHelper(MD5); }(Math)); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Reusable object var W = []; /** * SHA-1 hash algorithm. */ var SHA1 = C_algo.SHA1 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init([ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]); }, _doProcessBlock: function (M, offset) { // Shortcut var H = this._hash.words; // Working variables var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; // Computation for (var i = 0; i < 80; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; W[i] = (n << 1) | (n >>> 31); } var t = ((a << 5) | (a >>> 27)) + e + W[i]; if (i < 20) { t += ((b & c) | (~b & d)) + 0x5a827999; } else if (i < 40) { t += (b ^ c ^ d) + 0x6ed9eba1; } else if (i < 60) { t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; } else /* if (i < 80) */ { t += (b ^ c ^ d) - 0x359d3e2a; } e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t; } // Intermediate hash value H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; H[4] = (H[4] + e) | 0; }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; // Hash final blocks this._process(); // Return final computed hash return this._hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA1('message'); * var hash = CryptoJS.SHA1(wordArray); */ C.SHA1 = Hasher._createHelper(SHA1); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA1(message, key); */ C.HmacSHA1 = Hasher._createHmacHelper(SHA1); }()); (function (Math) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Initialization and round constants tables var H = []; var K = []; // Compute constants (function () { function isPrime(n) { var sqrtN = Math.sqrt(n); for (var factor = 2; factor <= sqrtN; factor++) { if (!(n % factor)) { return false; } } return true; } function getFractionalBits(n) { return ((n - (n | 0)) * 0x100000000) | 0; } var n = 2; var nPrime = 0; while (nPrime < 64) { if (isPrime(n)) { if (nPrime < 8) { H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2)); } K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3)); nPrime++; } n++; } }()); // Reusable object var W = []; /** * SHA-256 hash algorithm. */ var SHA256 = C_algo.SHA256 = Hasher.extend({ _doReset: function () { this._hash = new WordArray.init(H.slice(0)); }, _doProcessBlock: function (M, offset) { // Shortcut var H = this._hash.words; // Working variables var a = H[0]; var b = H[1]; var c = H[2]; var d = H[3]; var e = H[4]; var f = H[5]; var g = H[6]; var h = H[7]; // Computation for (var i = 0; i < 64; i++) { if (i < 16) { W[i] = M[offset + i] | 0; } else { var gamma0x = W[i - 15]; var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ ((gamma0x << 14) | (gamma0x >>> 18)) ^ (gamma0x >>> 3); var gamma1x = W[i - 2]; var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ ((gamma1x << 13) | (gamma1x >>> 19)) ^ (gamma1x >>> 10); W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; } var ch = (e & f) ^ (~e & g); var maj = (a & b) ^ (a & c) ^ (b & c); var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22)); var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25)); var t1 = h + sigma1 + ch + K[i] + W[i]; var t2 = sigma0 + maj; h = g; g = f; f = e; e = (d + t1) | 0; d = c; c = b; b = a; a = (t1 + t2) | 0; } // Intermediate hash value H[0] = (H[0] + a) | 0; H[1] = (H[1] + b) | 0; H[2] = (H[2] + c) | 0; H[3] = (H[3] + d) | 0; H[4] = (H[4] + e) | 0; H[5] = (H[5] + f) | 0; H[6] = (H[6] + g) | 0; H[7] = (H[7] + h) | 0; }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; data.sigBytes = dataWords.length * 4; // Hash final blocks this._process(); // Return final computed hash return this._hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA256('message'); * var hash = CryptoJS.SHA256(wordArray); */ C.SHA256 = Hasher._createHelper(SHA256); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA256(message, key); */ C.HmacSHA256 = Hasher._createHmacHelper(SHA256); }(Math)); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; /** * UTF-16 BE encoding strategy. */ var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = { /** * Converts a word array to a UTF-16 BE string. * * @param {WordArray} wordArray The word array. * * @return {string} The UTF-16 BE string. * * @static * * @example * * var utf16String = CryptoJS.enc.Utf16.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var utf16Chars = []; for (var i = 0; i < sigBytes; i += 2) { var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff; utf16Chars.push(String.fromCharCode(codePoint)); } return utf16Chars.join(''); }, /** * Converts a UTF-16 BE string to a word array. * * @param {string} utf16Str The UTF-16 BE string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Utf16.parse(utf16String); */ parse: function (utf16Str) { // Shortcut var utf16StrLength = utf16Str.length; // Convert var words = []; for (var i = 0; i < utf16StrLength; i++) { words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16); } return WordArray.create(words, utf16StrLength * 2); } }; /** * UTF-16 LE encoding strategy. */ C_enc.Utf16LE = { /** * Converts a word array to a UTF-16 LE string. * * @param {WordArray} wordArray The word array. * * @return {string} The UTF-16 LE string. * * @static * * @example * * var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray); */ stringify: function (wordArray) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; // Convert var utf16Chars = []; for (var i = 0; i < sigBytes; i += 2) { var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff); utf16Chars.push(String.fromCharCode(codePoint)); } return utf16Chars.join(''); }, /** * Converts a UTF-16 LE string to a word array. * * @param {string} utf16Str The UTF-16 LE string. * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str); */ parse: function (utf16Str) { // Shortcut var utf16StrLength = utf16Str.length; // Convert var words = []; for (var i = 0; i < utf16StrLength; i++) { words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16)); } return WordArray.create(words, utf16StrLength * 2); } }; function swapEndian(word) { return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff); } }()); (function () { // Check if typed arrays are supported if (typeof ArrayBuffer != 'function') { return; } // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; // Reference original init var superInit = WordArray.init; // Augment WordArray.init to handle typed arrays var subInit = WordArray.init = function (typedArray) { // Convert buffers to uint8 if (typedArray instanceof ArrayBuffer) { typedArray = new Uint8Array(typedArray); } // Convert other array views to uint8 if ( typedArray instanceof Int8Array || (typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray) || typedArray instanceof Int16Array || typedArray instanceof Uint16Array || typedArray instanceof Int32Array || typedArray instanceof Uint32Array || typedArray instanceof Float32Array || typedArray instanceof Float64Array ) { typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength); } // Handle Uint8Array if (typedArray instanceof Uint8Array) { // Shortcut var typedArrayByteLength = typedArray.byteLength; // Extract bytes var words = []; for (var i = 0; i < typedArrayByteLength; i++) { words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8); } // Initialize this word array superInit.call(this, words, typedArrayByteLength); } else { // Else call normal init superInit.apply(this, arguments); } }; subInit.prototype = WordArray; }()); /** @preserve (c) 2012 by Cédric Mesnil. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ (function (Math) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_algo = C.algo; // Constants table var _zl = WordArray.create([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]); var _zr = WordArray.create([ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]); var _sl = WordArray.create([ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ]); var _sr = WordArray.create([ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ]); var _hl = WordArray.create([ 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]); var _hr = WordArray.create([ 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]); /** * RIPEMD160 hash algorithm. */ var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({ _doReset: function () { this._hash = WordArray.create([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]); }, _doProcessBlock: function (M, offset) { // Swap endian for (var i = 0; i < 16; i++) { // Shortcuts var offset_i = offset + i; var M_offset_i = M[offset_i]; // Swap M[offset_i] = ( (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) ); } // Shortcut var H = this._hash.words; var hl = _hl.words; var hr = _hr.words; var zl = _zl.words; var zr = _zr.words; var sl = _sl.words; var sr = _sr.words; // Working variables var al, bl, cl, dl, el; var ar, br, cr, dr, er; ar = al = H[0]; br = bl = H[1]; cr = cl = H[2]; dr = dl = H[3]; er = el = H[4]; // Computation var t; for (var i = 0; i < 80; i += 1) { t = (al + M[offset+zl[i]])|0; if (i<16){ t += f1(bl,cl,dl) + hl[0]; } else if (i<32) { t += f2(bl,cl,dl) + hl[1]; } else if (i<48) { t += f3(bl,cl,dl) + hl[2]; } else if (i<64) { t += f4(bl,cl,dl) + hl[3]; } else {// if (i<80) { t += f5(bl,cl,dl) + hl[4]; } t = t|0; t = rotl(t,sl[i]); t = (t+el)|0; al = el; el = dl; dl = rotl(cl, 10); cl = bl; bl = t; t = (ar + M[offset+zr[i]])|0; if (i<16){ t += f5(br,cr,dr) + hr[0]; } else if (i<32) { t += f4(br,cr,dr) + hr[1]; } else if (i<48) { t += f3(br,cr,dr) + hr[2]; } else if (i<64) { t += f2(br,cr,dr) + hr[3]; } else {// if (i<80) { t += f1(br,cr,dr) + hr[4]; } t = t|0; t = rotl(t,sr[i]) ; t = (t+er)|0; ar = er; er = dr; dr = rotl(cr, 10); cr = br; br = t; } // Intermediate hash value t = (H[1] + cl + dr)|0; H[1] = (H[2] + dl + er)|0; H[2] = (H[3] + el + ar)|0; H[3] = (H[4] + al + br)|0; H[4] = (H[0] + bl + cr)|0; H[0] = t; }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00) ); data.sigBytes = (dataWords.length + 1) * 4; // Hash final blocks this._process(); // Shortcuts var hash = this._hash; var H = hash.words; // Swap endian for (var i = 0; i < 5; i++) { // Shortcut var H_i = H[i]; // Swap H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); } // Return final computed hash return hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; } }); function f1(x, y, z) { return ((x) ^ (y) ^ (z)); } function f2(x, y, z) { return (((x)&(y)) | ((~x)&(z))); } function f3(x, y, z) { return (((x) | (~(y))) ^ (z)); } function f4(x, y, z) { return (((x) & (z)) | ((y)&(~(z)))); } function f5(x, y, z) { return ((x) ^ ((y) |(~(z)))); } function rotl(x,n) { return (x<<n) | (x>>>(32-n)); } /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.RIPEMD160('message'); * var hash = CryptoJS.RIPEMD160(wordArray); */ C.RIPEMD160 = Hasher._createHelper(RIPEMD160); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacRIPEMD160(message, key); */ C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160); }(Math)); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var C_enc = C.enc; var Utf8 = C_enc.Utf8; var C_algo = C.algo; /** * HMAC algorithm. */ var HMAC = C_algo.HMAC = Base.extend({ /** * Initializes a newly created HMAC. * * @param {Hasher} hasher The hash algorithm to use. * @param {WordArray|string} key The secret key. * * @example * * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); */ init: function (hasher, key) { // Init hasher hasher = this._hasher = new hasher.init(); // Convert string to WordArray, else assume WordArray already if (typeof key == 'string') { key = Utf8.parse(key); } // Shortcuts var hasherBlockSize = hasher.blockSize; var hasherBlockSizeBytes = hasherBlockSize * 4; // Allow arbitrary length keys if (key.sigBytes > hasherBlockSizeBytes) { key = hasher.finalize(key); } // Clamp excess bits key.clamp(); // Clone key for inner and outer pads var oKey = this._oKey = key.clone(); var iKey = this._iKey = key.clone(); // Shortcuts var oKeyWords = oKey.words; var iKeyWords = iKey.words; // XOR keys with pad constants for (var i = 0; i < hasherBlockSize; i++) { oKeyWords[i] ^= 0x5c5c5c5c; iKeyWords[i] ^= 0x36363636; } oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; // Set initial values this.reset(); }, /** * Resets this HMAC to its initial state. * * @example * * hmacHasher.reset(); */ reset: function () { // Shortcut var hasher = this._hasher; // Reset hasher.reset(); hasher.update(this._iKey); }, /** * Updates this HMAC with a message. * * @param {WordArray|string} messageUpdate The message to append. * * @return {HMAC} This HMAC instance. * * @example * * hmacHasher.update('message'); * hmacHasher.update(wordArray); */ update: function (messageUpdate) { this._hasher.update(messageUpdate); // Chainable return this; }, /** * Finalizes the HMAC computation. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} messageUpdate (Optional) A final message update. * * @return {WordArray} The HMAC. * * @example * * var hmac = hmacHasher.finalize(); * var hmac = hmacHasher.finalize('message'); * var hmac = hmacHasher.finalize(wordArray); */ finalize: function (messageUpdate) { // Shortcut var hasher = this._hasher; // Compute HMAC var innerHash = hasher.finalize(messageUpdate); hasher.reset(); var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); return hmac; } }); }()); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var C_algo = C.algo; var SHA1 = C_algo.SHA1; var HMAC = C_algo.HMAC; /** * Password-Based Key Derivation Function 2 algorithm. */ var PBKDF2 = C_algo.PBKDF2 = Base.extend({ /** * Configuration options. * * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) * @property {Hasher} hasher The hasher to use. Default: SHA1 * @property {number} iterations The number of iterations to perform. Default: 1 */ cfg: Base.extend({ keySize: 128/32, hasher: SHA1, iterations: 1 }), /** * Initializes a newly created key derivation function. * * @param {Object} cfg (Optional) The configuration options to use for the derivation. * * @example * * var kdf = CryptoJS.algo.PBKDF2.create(); * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 }); * var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 }); */ init: function (cfg) { this.cfg = this.cfg.extend(cfg); }, /** * Computes the Password-Based Key Derivation Function 2. * * @param {WordArray|string} password The password. * @param {WordArray|string} salt A salt. * * @return {WordArray} The derived key. * * @example * * var key = kdf.compute(password, salt); */ compute: function (password, salt) { // Shortcut var cfg = this.cfg; // Init HMAC var hmac = HMAC.create(cfg.hasher, password); // Initial values var derivedKey = WordArray.create(); var blockIndex = WordArray.create([0x00000001]); // Shortcuts var derivedKeyWords = derivedKey.words; var blockIndexWords = blockIndex.words; var keySize = cfg.keySize; var iterations = cfg.iterations; // Generate key while (derivedKeyWords.length < keySize) { var block = hmac.update(salt).finalize(blockIndex); hmac.reset(); // Shortcuts var blockWords = block.words; var blockWordsLength = blockWords.length; // Iterations var intermediate = block; for (var i = 1; i < iterations; i++) { intermediate = hmac.finalize(intermediate); hmac.reset(); // Shortcut var intermediateWords = intermediate.words; // XOR intermediate with block for (var j = 0; j < blockWordsLength; j++) { blockWords[j] ^= intermediateWords[j]; } } derivedKey.concat(block); blockIndexWords[0]++; } derivedKey.sigBytes = keySize * 4; return derivedKey; } }); /** * Computes the Password-Based Key Derivation Function 2. * * @param {WordArray|string} password The password. * @param {WordArray|string} salt A salt. * @param {Object} cfg (Optional) The configuration options to use for this computation. * * @return {WordArray} The derived key. * * @static * * @example * * var key = CryptoJS.PBKDF2(password, salt); * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 }); * var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 }); */ C.PBKDF2 = function (password, salt, cfg) { return PBKDF2.create(cfg).compute(password, salt); }; }()); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var C_algo = C.algo; var MD5 = C_algo.MD5; /** * This key derivation function is meant to conform with EVP_BytesToKey. * www.openssl.org/docs/crypto/EVP_BytesToKey.html */ var EvpKDF = C_algo.EvpKDF = Base.extend({ /** * Configuration options. * * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) * @property {Hasher} hasher The hash algorithm to use. Default: MD5 * @property {number} iterations The number of iterations to perform. Default: 1 */ cfg: Base.extend({ keySize: 128/32, hasher: MD5, iterations: 1 }), /** * Initializes a newly created key derivation function. * * @param {Object} cfg (Optional) The configuration options to use for the derivation. * * @example * * var kdf = CryptoJS.algo.EvpKDF.create(); * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 }); * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 }); */ init: function (cfg) { this.cfg = this.cfg.extend(cfg); }, /** * Derives a key from a password. * * @param {WordArray|string} password The password. * @param {WordArray|string} salt A salt. * * @return {WordArray} The derived key. * * @example * * var key = kdf.compute(password, salt); */ compute: function (password, salt) { // Shortcut var cfg = this.cfg; // Init hasher var hasher = cfg.hasher.create(); // Initial values var derivedKey = WordArray.create(); // Shortcuts var derivedKeyWords = derivedKey.words; var keySize = cfg.keySize; var iterations = cfg.iterations; // Generate key while (derivedKeyWords.length < keySize) { if (block) { hasher.update(block); } var block = hasher.update(password).finalize(salt); hasher.reset(); // Iterations for (var i = 1; i < iterations; i++) { block = hasher.finalize(block); hasher.reset(); } derivedKey.concat(block); } derivedKey.sigBytes = keySize * 4; return derivedKey; } }); /** * Derives a key from a password. * * @param {WordArray|string} password The password. * @param {WordArray|string} salt A salt. * @param {Object} cfg (Optional) The configuration options to use for this computation. * * @return {WordArray} The derived key. * * @static * * @example * * var key = CryptoJS.EvpKDF(password, salt); * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); */ C.EvpKDF = function (password, salt, cfg) { return EvpKDF.create(cfg).compute(password, salt); }; }()); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_algo = C.algo; var SHA256 = C_algo.SHA256; /** * SHA-224 hash algorithm. */ var SHA224 = C_algo.SHA224 = SHA256.extend({ _doReset: function () { this._hash = new WordArray.init([ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]); }, _doFinalize: function () { var hash = SHA256._doFinalize.call(this); hash.sigBytes -= 4; return hash; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA224('message'); * var hash = CryptoJS.SHA224(wordArray); */ C.SHA224 = SHA256._createHelper(SHA224); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA224(message, key); */ C.HmacSHA224 = SHA256._createHmacHelper(SHA224); }()); (function (undefined) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var X32WordArray = C_lib.WordArray; /** * x64 namespace. */ var C_x64 = C.x64 = {}; /** * A 64-bit word. */ var X64Word = C_x64.Word = Base.extend({ /** * Initializes a newly created 64-bit word. * * @param {number} high The high 32 bits. * @param {number} low The low 32 bits. * * @example * * var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607); */ init: function (high, low) { this.high = high; this.low = low; } /** * Bitwise NOTs this word. * * @return {X64Word} A new x64-Word object after negating. * * @example * * var negated = x64Word.not(); */ // not: function () { // var high = ~this.high; // var low = ~this.low; // return X64Word.create(high, low); // }, /** * Bitwise ANDs this word with the passed word. * * @param {X64Word} word The x64-Word to AND with this word. * * @return {X64Word} A new x64-Word object after ANDing. * * @example * * var anded = x64Word.and(anotherX64Word); */ // and: function (word) { // var high = this.high & word.high; // var low = this.low & word.low; // return X64Word.create(high, low); // }, /** * Bitwise ORs this word with the passed word. * * @param {X64Word} word The x64-Word to OR with this word. * * @return {X64Word} A new x64-Word object after ORing. * * @example * * var ored = x64Word.or(anotherX64Word); */ // or: function (word) { // var high = this.high | word.high; // var low = this.low | word.low; // return X64Word.create(high, low); // }, /** * Bitwise XORs this word with the passed word. * * @param {X64Word} word The x64-Word to XOR with this word. * * @return {X64Word} A new x64-Word object after XORing. * * @example * * var xored = x64Word.xor(anotherX64Word); */ // xor: function (word) { // var high = this.high ^ word.high; // var low = this.low ^ word.low; // return X64Word.create(high, low); // }, /** * Shifts this word n bits to the left. * * @param {number} n The number of bits to shift. * * @return {X64Word} A new x64-Word object after shifting. * * @example * * var shifted = x64Word.shiftL(25); */ // shiftL: function (n) { // if (n < 32) { // var high = (this.high << n) | (this.low >>> (32 - n)); // var low = this.low << n; // } else { // var high = this.low << (n - 32); // var low = 0; // } // return X64Word.create(high, low); // }, /** * Shifts this word n bits to the right. * * @param {number} n The number of bits to shift. * * @return {X64Word} A new x64-Word object after shifting. * * @example * * var shifted = x64Word.shiftR(7); */ // shiftR: function (n) { // if (n < 32) { // var low = (this.low >>> n) | (this.high << (32 - n)); // var high = this.high >>> n; // } else { // var low = this.high >>> (n - 32); // var high = 0; // } // return X64Word.create(high, low); // }, /** * Rotates this word n bits to the left. * * @param {number} n The number of bits to rotate. * * @return {X64Word} A new x64-Word object after rotating. * * @example * * var rotated = x64Word.rotL(25); */ // rotL: function (n) { // return this.shiftL(n).or(this.shiftR(64 - n)); // }, /** * Rotates this word n bits to the right. * * @param {number} n The number of bits to rotate. * * @return {X64Word} A new x64-Word object after rotating. * * @example * * var rotated = x64Word.rotR(7); */ // rotR: function (n) { // return this.shiftR(n).or(this.shiftL(64 - n)); // }, /** * Adds this word with the passed word. * * @param {X64Word} word The x64-Word to add with this word. * * @return {X64Word} A new x64-Word object after adding. * * @example * * var added = x64Word.add(anotherX64Word); */ // add: function (word) { // var low = (this.low + word.low) | 0; // var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0; // var high = (this.high + word.high + carry) | 0; // return X64Word.create(high, low); // } }); /** * An array of 64-bit words. * * @property {Array} words The array of CryptoJS.x64.Word objects. * @property {number} sigBytes The number of significant bytes in this word array. */ var X64WordArray = C_x64.WordArray = Base.extend({ /** * Initializes a newly created word array. * * @param {Array} words (Optional) An array of CryptoJS.x64.Word objects. * @param {number} sigBytes (Optional) The number of significant bytes in the words. * * @example * * var wordArray = CryptoJS.x64.WordArray.create(); * * var wordArray = CryptoJS.x64.WordArray.create([ * CryptoJS.x64.Word.create(0x00010203, 0x04050607), * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) * ]); * * var wordArray = CryptoJS.x64.WordArray.create([ * CryptoJS.x64.Word.create(0x00010203, 0x04050607), * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) * ], 10); */ init: function (words, sigBytes) { words = this.words = words || []; if (sigBytes != undefined) { this.sigBytes = sigBytes; } else { this.sigBytes = words.length * 8; } }, /** * Converts this 64-bit word array to a 32-bit word array. * * @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array. * * @example * * var x32WordArray = x64WordArray.toX32(); */ toX32: function () { // Shortcuts var x64Words = this.words; var x64WordsLength = x64Words.length; // Convert var x32Words = []; for (var i = 0; i < x64WordsLength; i++) { var x64Word = x64Words[i]; x32Words.push(x64Word.high); x32Words.push(x64Word.low); } return X32WordArray.create(x32Words, this.sigBytes); }, /** * Creates a copy of this word array. * * @return {X64WordArray} The clone. * * @example * * var clone = x64WordArray.clone(); */ clone: function () { var clone = Base.clone.call(this); // Clone "words" array var words = clone.words = this.words.slice(0); // Clone each X64Word object var wordsLength = words.length; for (var i = 0; i < wordsLength; i++) { words[i] = words[i].clone(); } return clone; } }); }()); (function (Math) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var Hasher = C_lib.Hasher; var C_x64 = C.x64; var X64Word = C_x64.Word; var C_algo = C.algo; // Constants tables var RHO_OFFSETS = []; var PI_INDEXES = []; var ROUND_CONSTANTS = []; // Compute Constants (function () { // Compute rho offset constants var x = 1, y = 0; for (var t = 0; t < 24; t++) { RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64; var newX = y % 5; var newY = (2 * x + 3 * y) % 5; x = newX; y = newY; } // Compute pi index constants for (var x = 0; x < 5; x++) { for (var y = 0; y < 5; y++) { PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5; } } // Compute round constants var LFSR = 0x01; for (var i = 0; i < 24; i++) { var roundConstantMsw = 0; var roundConstantLsw = 0; for (var j = 0; j < 7; j++) { if (LFSR & 0x01) { var bitPosition = (1 << j) - 1; if (bitPosition < 32) { roundConstantLsw ^= 1 << bitPosition; } else /* if (bitPosition >= 32) */ { roundConstantMsw ^= 1 << (bitPosition - 32); } } // Compute next LFSR if (LFSR & 0x80) { // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1 LFSR = (LFSR << 1) ^ 0x71; } else { LFSR <<= 1; } } ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw); } }()); // Reusable objects for temporary values var T = []; (function () { for (var i = 0; i < 25; i++) { T[i] = X64Word.create(); } }()); /** * SHA-3 hash algorithm. */ var SHA3 = C_algo.SHA3 = Hasher.extend({ /** * Configuration options. * * @property {number} outputLength * The desired number of bits in the output hash. * Only values permitted are: 224, 256, 384, 512. * Default: 512 */ cfg: Hasher.cfg.extend({ outputLength: 512 }), _doReset: function () { var state = this._state = [] for (var i = 0; i < 25; i++) { state[i] = new X64Word.init(); } this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32; }, _doProcessBlock: function (M, offset) { // Shortcuts var state = this._state; var nBlockSizeLanes = this.blockSize / 2; // Absorb for (var i = 0; i < nBlockSizeLanes; i++) { // Shortcuts var M2i = M[offset + 2 * i]; var M2i1 = M[offset + 2 * i + 1]; // Swap endian M2i = ( (((M2i << 8) | (M2i >>> 24)) & 0x00ff00ff) | (((M2i << 24) | (M2i >>> 8)) & 0xff00ff00) ); M2i1 = ( (((M2i1 << 8) | (M2i1 >>> 24)) & 0x00ff00ff) | (((M2i1 << 24) | (M2i1 >>> 8)) & 0xff00ff00) ); // Absorb message into state var lane = state[i]; lane.high ^= M2i1; lane.low ^= M2i; } // Rounds for (var round = 0; round < 24; round++) { // Theta for (var x = 0; x < 5; x++) { // Mix column lanes var tMsw = 0, tLsw = 0; for (var y = 0; y < 5; y++) { var lane = state[x + 5 * y]; tMsw ^= lane.high; tLsw ^= lane.low; } // Temporary values var Tx = T[x]; Tx.high = tMsw; Tx.low = tLsw; } for (var x = 0; x < 5; x++) { // Shortcuts var Tx4 = T[(x + 4) % 5]; var Tx1 = T[(x + 1) % 5]; var Tx1Msw = Tx1.high; var Tx1Lsw = Tx1.low; // Mix surrounding columns var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31)); var tLsw = Tx4.low ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31)); for (var y = 0; y < 5; y++) { var lane = state[x + 5 * y]; lane.high ^= tMsw; lane.low ^= tLsw; } } // Rho Pi for (var laneIndex = 1; laneIndex < 25; laneIndex++) { // Shortcuts var lane = state[laneIndex]; var laneMsw = lane.high; var laneLsw = lane.low; var rhoOffset = RHO_OFFSETS[laneIndex]; // Rotate lanes if (rhoOffset < 32) { var tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset)); var tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset)); } else /* if (rhoOffset >= 32) */ { var tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset)); var tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset)); } // Transpose lanes var TPiLane = T[PI_INDEXES[laneIndex]]; TPiLane.high = tMsw; TPiLane.low = tLsw; } // Rho pi at x = y = 0 var T0 = T[0]; var state0 = state[0]; T0.high = state0.high; T0.low = state0.low; // Chi for (var x = 0; x < 5; x++) { for (var y = 0; y < 5; y++) { // Shortcuts var laneIndex = x + 5 * y; var lane = state[laneIndex]; var TLane = T[laneIndex]; var Tx1Lane = T[((x + 1) % 5) + 5 * y]; var Tx2Lane = T[((x + 2) % 5) + 5 * y]; // Mix rows lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high); lane.low = TLane.low ^ (~Tx1Lane.low & Tx2Lane.low); } } // Iota var lane = state[0]; var roundConstant = ROUND_CONSTANTS[round]; lane.high ^= roundConstant.high; lane.low ^= roundConstant.low;; } }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; var blockSizeBits = this.blockSize * 32; // Add padding dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32); dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80; data.sigBytes = dataWords.length * 4; // Hash final blocks this._process(); // Shortcuts var state = this._state; var outputLengthBytes = this.cfg.outputLength / 8; var outputLengthLanes = outputLengthBytes / 8; // Squeeze var hashWords = []; for (var i = 0; i < outputLengthLanes; i++) { // Shortcuts var lane = state[i]; var laneMsw = lane.high; var laneLsw = lane.low; // Swap endian laneMsw = ( (((laneMsw << 8) | (laneMsw >>> 24)) & 0x00ff00ff) | (((laneMsw << 24) | (laneMsw >>> 8)) & 0xff00ff00) ); laneLsw = ( (((laneLsw << 8) | (laneLsw >>> 24)) & 0x00ff00ff) | (((laneLsw << 24) | (laneLsw >>> 8)) & 0xff00ff00) ); // Squeeze state to retrieve hash hashWords.push(laneLsw); hashWords.push(laneMsw); } // Return final computed hash return new WordArray.init(hashWords, outputLengthBytes); }, clone: function () { var clone = Hasher.clone.call(this); var state = clone._state = this._state.slice(0); for (var i = 0; i < 25; i++) { state[i] = state[i].clone(); } return clone; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA3('message'); * var hash = CryptoJS.SHA3(wordArray); */ C.SHA3 = Hasher._createHelper(SHA3); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA3(message, key); */ C.HmacSHA3 = Hasher._createHmacHelper(SHA3); }(Math)); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Hasher = C_lib.Hasher; var C_x64 = C.x64; var X64Word = C_x64.Word; var X64WordArray = C_x64.WordArray; var C_algo = C.algo; function X64Word_create() { return X64Word.create.apply(X64Word, arguments); } // Constants var K = [ X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd), X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc), X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019), X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118), X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe), X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2), X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1), X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694), X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3), X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65), X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483), X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5), X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210), X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4), X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725), X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70), X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926), X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df), X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8), X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b), X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001), X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30), X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910), X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8), X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53), X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8), X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb), X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3), X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60), X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec), X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9), X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b), X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207), X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178), X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6), X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b), X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493), X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c), X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a), X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817) ]; // Reusable objects var W = []; (function () { for (var i = 0; i < 80; i++) { W[i] = X64Word_create(); } }()); /** * SHA-512 hash algorithm. */ var SHA512 = C_algo.SHA512 = Hasher.extend({ _doReset: function () { this._hash = new X64WordArray.init([ new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b), new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1), new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f), new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179) ]); }, _doProcessBlock: function (M, offset) { // Shortcuts var H = this._hash.words; var H0 = H[0]; var H1 = H[1]; var H2 = H[2]; var H3 = H[3]; var H4 = H[4]; var H5 = H[5]; var H6 = H[6]; var H7 = H[7]; var H0h = H0.high; var H0l = H0.low; var H1h = H1.high; var H1l = H1.low; var H2h = H2.high; var H2l = H2.low; var H3h = H3.high; var H3l = H3.low; var H4h = H4.high; var H4l = H4.low; var H5h = H5.high; var H5l = H5.low; var H6h = H6.high; var H6l = H6.low; var H7h = H7.high; var H7l = H7.low; // Working variables var ah = H0h; var al = H0l; var bh = H1h; var bl = H1l; var ch = H2h; var cl = H2l; var dh = H3h; var dl = H3l; var eh = H4h; var el = H4l; var fh = H5h; var fl = H5l; var gh = H6h; var gl = H6l; var hh = H7h; var hl = H7l; // Rounds for (var i = 0; i < 80; i++) { // Shortcut var Wi = W[i]; // Extend message if (i < 16) { var Wih = Wi.high = M[offset + i * 2] | 0; var Wil = Wi.low = M[offset + i * 2 + 1] | 0; } else { // Gamma0 var gamma0x = W[i - 15]; var gamma0xh = gamma0x.high; var gamma0xl = gamma0x.low; var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7); var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25)); // Gamma1 var gamma1x = W[i - 2]; var gamma1xh = gamma1x.high; var gamma1xl = gamma1x.low; var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6); var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26)); // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] var Wi7 = W[i - 7]; var Wi7h = Wi7.high; var Wi7l = Wi7.low; var Wi16 = W[i - 16]; var Wi16h = Wi16.high; var Wi16l = Wi16.low; var Wil = gamma0l + Wi7l; var Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0); var Wil = Wil + gamma1l; var Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0); var Wil = Wil + Wi16l; var Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0); Wi.high = Wih; Wi.low = Wil; } var chh = (eh & fh) ^ (~eh & gh); var chl = (el & fl) ^ (~el & gl); var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch); var majl = (al & bl) ^ (al & cl) ^ (bl & cl); var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7)); var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7)); var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9)); var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9)); // t1 = h + sigma1 + ch + K[i] + W[i] var Ki = K[i]; var Kih = Ki.high; var Kil = Ki.low; var t1l = hl + sigma1l; var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0); var t1l = t1l + chl; var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0); var t1l = t1l + Kil; var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0); var t1l = t1l + Wil; var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0); // t2 = sigma0 + maj var t2l = sigma0l + majl; var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0); // Update working variables hh = gh; hl = gl; gh = fh; gl = fl; fh = eh; fl = el; el = (dl + t1l) | 0; eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0; dh = ch; dl = cl; ch = bh; cl = bl; bh = ah; bl = al; al = (t1l + t2l) | 0; ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0; } // Intermediate hash value H0l = H0.low = (H0l + al); H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0)); H1l = H1.low = (H1l + bl); H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0)); H2l = H2.low = (H2l + cl); H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0)); H3l = H3.low = (H3l + dl); H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0)); H4l = H4.low = (H4l + el); H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0)); H5l = H5.low = (H5l + fl); H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0)); H6l = H6.low = (H6l + gl); H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0)); H7l = H7.low = (H7l + hl); H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0)); }, _doFinalize: function () { // Shortcuts var data = this._data; var dataWords = data.words; var nBitsTotal = this._nDataBytes * 8; var nBitsLeft = data.sigBytes * 8; // Add padding dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000); dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal; data.sigBytes = dataWords.length * 4; // Hash final blocks this._process(); // Convert hash to 32-bit word array before returning var hash = this._hash.toX32(); // Return final computed hash return hash; }, clone: function () { var clone = Hasher.clone.call(this); clone._hash = this._hash.clone(); return clone; }, blockSize: 1024/32 }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA512('message'); * var hash = CryptoJS.SHA512(wordArray); */ C.SHA512 = Hasher._createHelper(SHA512); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA512(message, key); */ C.HmacSHA512 = Hasher._createHmacHelper(SHA512); }()); (function () { // Shortcuts var C = CryptoJS; var C_x64 = C.x64; var X64Word = C_x64.Word; var X64WordArray = C_x64.WordArray; var C_algo = C.algo; var SHA512 = C_algo.SHA512; /** * SHA-384 hash algorithm. */ var SHA384 = C_algo.SHA384 = SHA512.extend({ _doReset: function () { this._hash = new X64WordArray.init([ new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507), new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939), new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511), new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4) ]); }, _doFinalize: function () { var hash = SHA512._doFinalize.call(this); hash.sigBytes -= 16; return hash; } }); /** * Shortcut function to the hasher's object interface. * * @param {WordArray|string} message The message to hash. * * @return {WordArray} The hash. * * @static * * @example * * var hash = CryptoJS.SHA384('message'); * var hash = CryptoJS.SHA384(wordArray); */ C.SHA384 = SHA512._createHelper(SHA384); /** * Shortcut function to the HMAC's object interface. * * @param {WordArray|string} message The message to hash. * @param {WordArray|string} key The secret key. * * @return {WordArray} The HMAC. * * @static * * @example * * var hmac = CryptoJS.HmacSHA384(message, key); */ C.HmacSHA384 = SHA512._createHmacHelper(SHA384); }()); /** * Cipher core components. */ CryptoJS.lib.Cipher || (function (undefined) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var Base = C_lib.Base; var WordArray = C_lib.WordArray; var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; var C_enc = C.enc; var Utf8 = C_enc.Utf8; var Base64 = C_enc.Base64; var C_algo = C.algo; var EvpKDF = C_algo.EvpKDF; /** * Abstract base cipher template. * * @property {number} keySize This cipher's key size. Default: 4 (128 bits) * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. */ var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ /** * Configuration options. * * @property {WordArray} iv The IV to use for this operation. */ cfg: Base.extend(), /** * Creates this cipher in encryption mode. * * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {Cipher} A cipher instance. * * @static * * @example * * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); */ createEncryptor: function (key, cfg) { return this.create(this._ENC_XFORM_MODE, key, cfg); }, /** * Creates this cipher in decryption mode. * * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {Cipher} A cipher instance. * * @static * * @example * * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); */ createDecryptor: function (key, cfg) { return this.create(this._DEC_XFORM_MODE, key, cfg); }, /** * Initializes a newly created cipher. * * @param {number} xformMode Either the encryption or decryption transormation mode constant. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @example * * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); */ init: function (xformMode, key, cfg) { // Apply config defaults this.cfg = this.cfg.extend(cfg); // Store transform mode and key this._xformMode = xformMode; this._key = key; // Set initial values this.reset(); }, /** * Resets this cipher to its initial state. * * @example * * cipher.reset(); */ reset: function () { // Reset data buffer BufferedBlockAlgorithm.reset.call(this); // Perform concrete-cipher logic this._doReset(); }, /** * Adds data to be encrypted or decrypted. * * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. * * @return {WordArray} The data after processing. * * @example * * var encrypted = cipher.process('data'); * var encrypted = cipher.process(wordArray); */ process: function (dataUpdate) { // Append this._append(dataUpdate); // Process available blocks return this._process(); }, /** * Finalizes the encryption or decryption process. * Note that the finalize operation is effectively a destructive, read-once operation. * * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. * * @return {WordArray} The data after final processing. * * @example * * var encrypted = cipher.finalize(); * var encrypted = cipher.finalize('data'); * var encrypted = cipher.finalize(wordArray); */ finalize: function (dataUpdate) { // Final data update if (dataUpdate) { this._append(dataUpdate); } // Perform concrete-cipher logic var finalProcessedData = this._doFinalize(); return finalProcessedData; }, keySize: 128/32, ivSize: 128/32, _ENC_XFORM_MODE: 1, _DEC_XFORM_MODE: 2, /** * Creates shortcut functions to a cipher's object interface. * * @param {Cipher} cipher The cipher to create a helper for. * * @return {Object} An object with encrypt and decrypt shortcut functions. * * @static * * @example * * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); */ _createHelper: (function () { function selectCipherStrategy(key) { if (typeof key == 'string') { return PasswordBasedCipher; } else { return SerializableCipher; } } return function (cipher) { return { encrypt: function (message, key, cfg) { return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); }, decrypt: function (ciphertext, key, cfg) { return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); } }; }; }()) }); /** * Abstract base stream cipher template. * * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) */ var StreamCipher = C_lib.StreamCipher = Cipher.extend({ _doFinalize: function () { // Process partial blocks var finalProcessedBlocks = this._process(!!'flush'); return finalProcessedBlocks; }, blockSize: 1 }); /** * Mode namespace. */ var C_mode = C.mode = {}; /** * Abstract base block cipher mode template. */ var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ /** * Creates this mode for encryption. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @static * * @example * * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); */ createEncryptor: function (cipher, iv) { return this.Encryptor.create(cipher, iv); }, /** * Creates this mode for decryption. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @static * * @example * * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); */ createDecryptor: function (cipher, iv) { return this.Decryptor.create(cipher, iv); }, /** * Initializes a newly created mode. * * @param {Cipher} cipher A block cipher instance. * @param {Array} iv The IV words. * * @example * * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); */ init: function (cipher, iv) { this._cipher = cipher; this._iv = iv; } }); /** * Cipher Block Chaining mode. */ var CBC = C_mode.CBC = (function () { /** * Abstract base CBC mode. */ var CBC = BlockCipherMode.extend(); /** * CBC encryptor. */ CBC.Encryptor = CBC.extend({ /** * Processes the data block at offset. * * @param {Array} words The data words to operate on. * @param {number} offset The offset where the block starts. * * @example * * mode.processBlock(data.words, offset); */ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher; var blockSize = cipher.blockSize; // XOR and encrypt xorBlock.call(this, words, offset, blockSize); cipher.encryptBlock(words, offset); // Remember this block to use with next block this._prevBlock = words.slice(offset, offset + blockSize); } }); /** * CBC decryptor. */ CBC.Decryptor = CBC.extend({ /** * Processes the data block at offset. * * @param {Array} words The data words to operate on. * @param {number} offset The offset where the block starts. * * @example * * mode.processBlock(data.words, offset); */ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher; var blockSize = cipher.blockSize; // Remember this block to use with next block var thisBlock = words.slice(offset, offset + blockSize); // Decrypt and XOR cipher.decryptBlock(words, offset); xorBlock.call(this, words, offset, blockSize); // This block becomes the previous block this._prevBlock = thisBlock; } }); function xorBlock(words, offset, blockSize) { // Shortcut var iv = this._iv; // Choose mixing block if (iv) { var block = iv; // Remove IV for subsequent blocks this._iv = undefined; } else { var block = this._prevBlock; } // XOR blocks for (var i = 0; i < blockSize; i++) { words[offset + i] ^= block[i]; } } return CBC; }()); /** * Padding namespace. */ var C_pad = C.pad = {}; /** * PKCS #5/7 padding strategy. */ var Pkcs7 = C_pad.Pkcs7 = { /** * Pads data using the algorithm defined in PKCS #5/7. * * @param {WordArray} data The data to pad. * @param {number} blockSize The multiple that the data should be padded to. * * @static * * @example * * CryptoJS.pad.Pkcs7.pad(wordArray, 4); */ pad: function (data, blockSize) { // Shortcut var blockSizeBytes = blockSize * 4; // Count padding bytes var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; // Create padding word var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; // Create padding var paddingWords = []; for (var i = 0; i < nPaddingBytes; i += 4) { paddingWords.push(paddingWord); } var padding = WordArray.create(paddingWords, nPaddingBytes); // Add padding data.concat(padding); }, /** * Unpads data that had been padded using the algorithm defined in PKCS #5/7. * * @param {WordArray} data The data to unpad. * * @static * * @example * * CryptoJS.pad.Pkcs7.unpad(wordArray); */ unpad: function (data) { // Get number of padding bytes from last byte var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; // Remove padding data.sigBytes -= nPaddingBytes; } }; /** * Abstract base block cipher template. * * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) */ var BlockCipher = C_lib.BlockCipher = Cipher.extend({ /** * Configuration options. * * @property {Mode} mode The block mode to use. Default: CBC * @property {Padding} padding The padding strategy to use. Default: Pkcs7 */ cfg: Cipher.cfg.extend({ mode: CBC, padding: Pkcs7 }), reset: function () { // Reset cipher Cipher.reset.call(this); // Shortcuts var cfg = this.cfg; var iv = cfg.iv; var mode = cfg.mode; // Reset block mode if (this._xformMode == this._ENC_XFORM_MODE) { var modeCreator = mode.createEncryptor; } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { var modeCreator = mode.createDecryptor; // Keep at least one block in the buffer for unpadding this._minBufferSize = 1; } if (this._mode && this._mode.__creator == modeCreator) { this._mode.init(this, iv && iv.words); } else { this._mode = modeCreator.call(mode, this, iv && iv.words); this._mode.__creator = modeCreator; } }, _doProcessBlock: function (words, offset) { this._mode.processBlock(words, offset); }, _doFinalize: function () { // Shortcut var padding = this.cfg.padding; // Finalize if (this._xformMode == this._ENC_XFORM_MODE) { // Pad data padding.pad(this._data, this.blockSize); // Process final blocks var finalProcessedBlocks = this._process(!!'flush'); } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { // Process final blocks var finalProcessedBlocks = this._process(!!'flush'); // Unpad data padding.unpad(finalProcessedBlocks); } return finalProcessedBlocks; }, blockSize: 128/32 }); /** * A collection of cipher parameters. * * @property {WordArray} ciphertext The raw ciphertext. * @property {WordArray} key The key to this ciphertext. * @property {WordArray} iv The IV used in the ciphering operation. * @property {WordArray} salt The salt used with a key derivation function. * @property {Cipher} algorithm The cipher algorithm. * @property {Mode} mode The block mode used in the ciphering operation. * @property {Padding} padding The padding scheme used in the ciphering operation. * @property {number} blockSize The block size of the cipher. * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. */ var CipherParams = C_lib.CipherParams = Base.extend({ /** * Initializes a newly created cipher params object. * * @param {Object} cipherParams An object with any of the possible cipher parameters. * * @example * * var cipherParams = CryptoJS.lib.CipherParams.create({ * ciphertext: ciphertextWordArray, * key: keyWordArray, * iv: ivWordArray, * salt: saltWordArray, * algorithm: CryptoJS.algo.AES, * mode: CryptoJS.mode.CBC, * padding: CryptoJS.pad.PKCS7, * blockSize: 4, * formatter: CryptoJS.format.OpenSSL * }); */ init: function (cipherParams) { this.mixIn(cipherParams); }, /** * Converts this cipher params object to a string. * * @param {Format} formatter (Optional) The formatting strategy to use. * * @return {string} The stringified cipher params. * * @throws Error If neither the formatter nor the default formatter is set. * * @example * * var string = cipherParams + ''; * var string = cipherParams.toString(); * var string = cipherParams.toString(CryptoJS.format.OpenSSL); */ toString: function (formatter) { return (formatter || this.formatter).stringify(this); } }); /** * Format namespace. */ var C_format = C.format = {}; /** * OpenSSL formatting strategy. */ var OpenSSLFormatter = C_format.OpenSSL = { /** * Converts a cipher params object to an OpenSSL-compatible string. * * @param {CipherParams} cipherParams The cipher params object. * * @return {string} The OpenSSL-compatible string. * * @static * * @example * * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); */ stringify: function (cipherParams) { // Shortcuts var ciphertext = cipherParams.ciphertext; var salt = cipherParams.salt; // Format if (salt) { var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); } else { var wordArray = ciphertext; } return wordArray.toString(Base64); }, /** * Converts an OpenSSL-compatible string to a cipher params object. * * @param {string} openSSLStr The OpenSSL-compatible string. * * @return {CipherParams} The cipher params object. * * @static * * @example * * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); */ parse: function (openSSLStr) { // Parse base64 var ciphertext = Base64.parse(openSSLStr); // Shortcut var ciphertextWords = ciphertext.words; // Test for salt if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { // Extract salt var salt = WordArray.create(ciphertextWords.slice(2, 4)); // Remove salt from ciphertext ciphertextWords.splice(0, 4); ciphertext.sigBytes -= 16; } return CipherParams.create({ ciphertext: ciphertext, salt: salt }); } }; /** * A cipher wrapper that returns ciphertext as a serializable cipher params object. */ var SerializableCipher = C_lib.SerializableCipher = Base.extend({ /** * Configuration options. * * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL */ cfg: Base.extend({ format: OpenSSLFormatter }), /** * Encrypts a message. * * @param {Cipher} cipher The cipher algorithm to use. * @param {WordArray|string} message The message to encrypt. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {CipherParams} A cipher params object. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); */ encrypt: function (cipher, message, key, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Encrypt var encryptor = cipher.createEncryptor(key, cfg); var ciphertext = encryptor.finalize(message); // Shortcut var cipherCfg = encryptor.cfg; // Create and return serializable cipher params return CipherParams.create({ ciphertext: ciphertext, key: key, iv: cipherCfg.iv, algorithm: cipher, mode: cipherCfg.mode, padding: cipherCfg.padding, blockSize: cipher.blockSize, formatter: cfg.format }); }, /** * Decrypts serialized ciphertext. * * @param {Cipher} cipher The cipher algorithm to use. * @param {CipherParams|string} ciphertext The ciphertext to decrypt. * @param {WordArray} key The key. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {WordArray} The plaintext. * * @static * * @example * * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); */ decrypt: function (cipher, ciphertext, key, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Convert string to CipherParams ciphertext = this._parse(ciphertext, cfg.format); // Decrypt var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); return plaintext; }, /** * Converts serialized ciphertext to CipherParams, * else assumed CipherParams already and returns ciphertext unchanged. * * @param {CipherParams|string} ciphertext The ciphertext. * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. * * @return {CipherParams} The unserialized ciphertext. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); */ _parse: function (ciphertext, format) { if (typeof ciphertext == 'string') { return format.parse(ciphertext, this); } else { return ciphertext; } } }); /** * Key derivation function namespace. */ var C_kdf = C.kdf = {}; /** * OpenSSL key derivation function. */ var OpenSSLKdf = C_kdf.OpenSSL = { /** * Derives a key and IV from a password. * * @param {string} password The password to derive from. * @param {number} keySize The size in words of the key to generate. * @param {number} ivSize The size in words of the IV to generate. * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. * * @return {CipherParams} A cipher params object with the key, IV, and salt. * * @static * * @example * * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); */ execute: function (password, keySize, ivSize, salt) { // Generate random salt if (!salt) { salt = WordArray.random(64/8); } // Derive key and IV var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); // Separate key and IV var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); key.sigBytes = keySize * 4; // Return params return CipherParams.create({ key: key, iv: iv, salt: salt }); } }; /** * A serializable cipher wrapper that derives the key from a password, * and returns ciphertext as a serializable cipher params object. */ var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ /** * Configuration options. * * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL */ cfg: SerializableCipher.cfg.extend({ kdf: OpenSSLKdf }), /** * Encrypts a message using a password. * * @param {Cipher} cipher The cipher algorithm to use. * @param {WordArray|string} message The message to encrypt. * @param {string} password The password. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {CipherParams} A cipher params object. * * @static * * @example * * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); */ encrypt: function (cipher, message, password, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Derive key and other params var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize); // Add IV to config cfg.iv = derivedParams.iv; // Encrypt var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); // Mix in derived params ciphertext.mixIn(derivedParams); return ciphertext; }, /** * Decrypts serialized ciphertext using a password. * * @param {Cipher} cipher The cipher algorithm to use. * @param {CipherParams|string} ciphertext The ciphertext to decrypt. * @param {string} password The password. * @param {Object} cfg (Optional) The configuration options to use for this operation. * * @return {WordArray} The plaintext. * * @static * * @example * * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); */ decrypt: function (cipher, ciphertext, password, cfg) { // Apply config defaults cfg = this.cfg.extend(cfg); // Convert string to CipherParams ciphertext = this._parse(ciphertext, cfg.format); // Derive key and other params var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt); // Add IV to config cfg.iv = derivedParams.iv; // Decrypt var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); return plaintext; } }); }()); /** * Cipher Feedback block mode. */ CryptoJS.mode.CFB = (function () { var CFB = CryptoJS.lib.BlockCipherMode.extend(); CFB.Encryptor = CFB.extend({ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher; var blockSize = cipher.blockSize; generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher); // Remember this block to use with next block this._prevBlock = words.slice(offset, offset + blockSize); } }); CFB.Decryptor = CFB.extend({ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher; var blockSize = cipher.blockSize; // Remember this block to use with next block var thisBlock = words.slice(offset, offset + blockSize); generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher); // This block becomes the previous block this._prevBlock = thisBlock; } }); function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) { // Shortcut var iv = this._iv; // Generate keystream if (iv) { var keystream = iv.slice(0); // Remove IV for subsequent blocks this._iv = undefined; } else { var keystream = this._prevBlock; } cipher.encryptBlock(keystream, 0); // Encrypt for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } return CFB; }()); /** * Electronic Codebook block mode. */ CryptoJS.mode.ECB = (function () { var ECB = CryptoJS.lib.BlockCipherMode.extend(); ECB.Encryptor = ECB.extend({ processBlock: function (words, offset) { this._cipher.encryptBlock(words, offset); } }); ECB.Decryptor = ECB.extend({ processBlock: function (words, offset) { this._cipher.decryptBlock(words, offset); } }); return ECB; }()); /** * ANSI X.923 padding strategy. */ CryptoJS.pad.AnsiX923 = { pad: function (data, blockSize) { // Shortcuts var dataSigBytes = data.sigBytes; var blockSizeBytes = blockSize * 4; // Count padding bytes var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes; // Compute last byte position var lastBytePos = dataSigBytes + nPaddingBytes - 1; // Pad data.clamp(); data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8); data.sigBytes += nPaddingBytes; }, unpad: function (data) { // Get number of padding bytes from last byte var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; // Remove padding data.sigBytes -= nPaddingBytes; } }; /** * ISO 10126 padding strategy. */ CryptoJS.pad.Iso10126 = { pad: function (data, blockSize) { // Shortcut var blockSizeBytes = blockSize * 4; // Count padding bytes var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; // Pad data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)). concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1)); }, unpad: function (data) { // Get number of padding bytes from last byte var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; // Remove padding data.sigBytes -= nPaddingBytes; } }; /** * ISO/IEC 9797-1 Padding Method 2. */ CryptoJS.pad.Iso97971 = { pad: function (data, blockSize) { // Add 0x80 byte data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1)); // Zero pad the rest CryptoJS.pad.ZeroPadding.pad(data, blockSize); }, unpad: function (data) { // Remove zero padding CryptoJS.pad.ZeroPadding.unpad(data); // Remove one more byte -- the 0x80 byte data.sigBytes--; } }; /** * Output Feedback block mode. */ CryptoJS.mode.OFB = (function () { var OFB = CryptoJS.lib.BlockCipherMode.extend(); var Encryptor = OFB.Encryptor = OFB.extend({ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher var blockSize = cipher.blockSize; var iv = this._iv; var keystream = this._keystream; // Generate keystream if (iv) { keystream = this._keystream = iv.slice(0); // Remove IV for subsequent blocks this._iv = undefined; } cipher.encryptBlock(keystream, 0); // Encrypt for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } }); OFB.Decryptor = Encryptor; return OFB; }()); /** * A noop padding strategy. */ CryptoJS.pad.NoPadding = { pad: function () { }, unpad: function () { } }; (function (undefined) { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var CipherParams = C_lib.CipherParams; var C_enc = C.enc; var Hex = C_enc.Hex; var C_format = C.format; var HexFormatter = C_format.Hex = { /** * Converts the ciphertext of a cipher params object to a hexadecimally encoded string. * * @param {CipherParams} cipherParams The cipher params object. * * @return {string} The hexadecimally encoded string. * * @static * * @example * * var hexString = CryptoJS.format.Hex.stringify(cipherParams); */ stringify: function (cipherParams) { return cipherParams.ciphertext.toString(Hex); }, /** * Converts a hexadecimally encoded ciphertext string to a cipher params object. * * @param {string} input The hexadecimally encoded string. * * @return {CipherParams} The cipher params object. * * @static * * @example * * var cipherParams = CryptoJS.format.Hex.parse(hexString); */ parse: function (input) { var ciphertext = Hex.parse(input); return CipherParams.create({ ciphertext: ciphertext }); } }; }()); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var BlockCipher = C_lib.BlockCipher; var C_algo = C.algo; // Lookup tables var SBOX = []; var INV_SBOX = []; var SUB_MIX_0 = []; var SUB_MIX_1 = []; var SUB_MIX_2 = []; var SUB_MIX_3 = []; var INV_SUB_MIX_0 = []; var INV_SUB_MIX_1 = []; var INV_SUB_MIX_2 = []; var INV_SUB_MIX_3 = []; // Compute lookup tables (function () { // Compute double table var d = []; for (var i = 0; i < 256; i++) { if (i < 128) { d[i] = i << 1; } else { d[i] = (i << 1) ^ 0x11b; } } // Walk GF(2^8) var x = 0; var xi = 0; for (var i = 0; i < 256; i++) { // Compute sbox var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; SBOX[x] = sx; INV_SBOX[sx] = x; // Compute multiplication var x2 = d[x]; var x4 = d[x2]; var x8 = d[x4]; // Compute sub bytes, mix columns tables var t = (d[sx] * 0x101) ^ (sx * 0x1010100); SUB_MIX_0[x] = (t << 24) | (t >>> 8); SUB_MIX_1[x] = (t << 16) | (t >>> 16); SUB_MIX_2[x] = (t << 8) | (t >>> 24); SUB_MIX_3[x] = t; // Compute inv sub bytes, inv mix columns tables var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); INV_SUB_MIX_3[sx] = t; // Compute next counter if (!x) { x = xi = 1; } else { x = x2 ^ d[d[d[x8 ^ x2]]]; xi ^= d[d[xi]]; } } }()); // Precomputed Rcon lookup var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; /** * AES block cipher algorithm. */ var AES = C_algo.AES = BlockCipher.extend({ _doReset: function () { // Skip reset of nRounds has been set before and key did not change if (this._nRounds && this._keyPriorReset === this._key) { return; } // Shortcuts var key = this._keyPriorReset = this._key; var keyWords = key.words; var keySize = key.sigBytes / 4; // Compute number of rounds var nRounds = this._nRounds = keySize + 6; // Compute number of key schedule rows var ksRows = (nRounds + 1) * 4; // Compute key schedule var keySchedule = this._keySchedule = []; for (var ksRow = 0; ksRow < ksRows; ksRow++) { if (ksRow < keySize) { keySchedule[ksRow] = keyWords[ksRow]; } else { var t = keySchedule[ksRow - 1]; if (!(ksRow % keySize)) { // Rot word t = (t << 8) | (t >>> 24); // Sub word t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; // Mix Rcon t ^= RCON[(ksRow / keySize) | 0] << 24; } else if (keySize > 6 && ksRow % keySize == 4) { // Sub word t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; } keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; } } // Compute inv key schedule var invKeySchedule = this._invKeySchedule = []; for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { var ksRow = ksRows - invKsRow; if (invKsRow % 4) { var t = keySchedule[ksRow]; } else { var t = keySchedule[ksRow - 4]; } if (invKsRow < 4 || ksRow <= 4) { invKeySchedule[invKsRow] = t; } else { invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; } } }, encryptBlock: function (M, offset) { this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); }, decryptBlock: function (M, offset) { // Swap 2nd and 4th rows var t = M[offset + 1]; M[offset + 1] = M[offset + 3]; M[offset + 3] = t; this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); // Inv swap 2nd and 4th rows var t = M[offset + 1]; M[offset + 1] = M[offset + 3]; M[offset + 3] = t; }, _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { // Shortcut var nRounds = this._nRounds; // Get input, add round key var s0 = M[offset] ^ keySchedule[0]; var s1 = M[offset + 1] ^ keySchedule[1]; var s2 = M[offset + 2] ^ keySchedule[2]; var s3 = M[offset + 3] ^ keySchedule[3]; // Key schedule row counter var ksRow = 4; // Rounds for (var round = 1; round < nRounds; round++) { // Shift rows, sub bytes, mix columns, add round key var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; // Update state s0 = t0; s1 = t1; s2 = t2; s3 = t3; } // Shift rows, sub bytes, add round key var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; // Set output M[offset] = t0; M[offset + 1] = t1; M[offset + 2] = t2; M[offset + 3] = t3; }, keySize: 256/32 }); /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); */ C.AES = BlockCipher._createHelper(AES); }()); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var BlockCipher = C_lib.BlockCipher; var C_algo = C.algo; // Permuted Choice 1 constants var PC1 = [ 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 ]; // Permuted Choice 2 constants var PC2 = [ 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 ]; // Cumulative bit shift constants var BIT_SHIFTS = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28]; // SBOXes and round permutation constants var SBOX_P = [ { 0x0: 0x808200, 0x10000000: 0x8000, 0x20000000: 0x808002, 0x30000000: 0x2, 0x40000000: 0x200, 0x50000000: 0x808202, 0x60000000: 0x800202, 0x70000000: 0x800000, 0x80000000: 0x202, 0x90000000: 0x800200, 0xa0000000: 0x8200, 0xb0000000: 0x808000, 0xc0000000: 0x8002, 0xd0000000: 0x800002, 0xe0000000: 0x0, 0xf0000000: 0x8202, 0x8000000: 0x0, 0x18000000: 0x808202, 0x28000000: 0x8202, 0x38000000: 0x8000, 0x48000000: 0x808200, 0x58000000: 0x200, 0x68000000: 0x808002, 0x78000000: 0x2, 0x88000000: 0x800200, 0x98000000: 0x8200, 0xa8000000: 0x808000, 0xb8000000: 0x800202, 0xc8000000: 0x800002, 0xd8000000: 0x8002, 0xe8000000: 0x202, 0xf8000000: 0x800000, 0x1: 0x8000, 0x10000001: 0x2, 0x20000001: 0x808200, 0x30000001: 0x800000, 0x40000001: 0x808002, 0x50000001: 0x8200, 0x60000001: 0x200, 0x70000001: 0x800202, 0x80000001: 0x808202, 0x90000001: 0x808000, 0xa0000001: 0x800002, 0xb0000001: 0x8202, 0xc0000001: 0x202, 0xd0000001: 0x800200, 0xe0000001: 0x8002, 0xf0000001: 0x0, 0x8000001: 0x808202, 0x18000001: 0x808000, 0x28000001: 0x800000, 0x38000001: 0x200, 0x48000001: 0x8000, 0x58000001: 0x800002, 0x68000001: 0x2, 0x78000001: 0x8202, 0x88000001: 0x8002, 0x98000001: 0x800202, 0xa8000001: 0x202, 0xb8000001: 0x808200, 0xc8000001: 0x800200, 0xd8000001: 0x0, 0xe8000001: 0x8200, 0xf8000001: 0x808002 }, { 0x0: 0x40084010, 0x1000000: 0x4000, 0x2000000: 0x80000, 0x3000000: 0x40080010, 0x4000000: 0x40000010, 0x5000000: 0x40084000, 0x6000000: 0x40004000, 0x7000000: 0x10, 0x8000000: 0x84000, 0x9000000: 0x40004010, 0xa000000: 0x40000000, 0xb000000: 0x84010, 0xc000000: 0x80010, 0xd000000: 0x0, 0xe000000: 0x4010, 0xf000000: 0x40080000, 0x800000: 0x40004000, 0x1800000: 0x84010, 0x2800000: 0x10, 0x3800000: 0x40004010, 0x4800000: 0x40084010, 0x5800000: 0x40000000, 0x6800000: 0x80000, 0x7800000: 0x40080010, 0x8800000: 0x80010, 0x9800000: 0x0, 0xa800000: 0x4000, 0xb800000: 0x40080000, 0xc800000: 0x40000010, 0xd800000: 0x84000, 0xe800000: 0x40084000, 0xf800000: 0x4010, 0x10000000: 0x0, 0x11000000: 0x40080010, 0x12000000: 0x40004010, 0x13000000: 0x40084000, 0x14000000: 0x40080000, 0x15000000: 0x10, 0x16000000: 0x84010, 0x17000000: 0x4000, 0x18000000: 0x4010, 0x19000000: 0x80000, 0x1a000000: 0x80010, 0x1b000000: 0x40000010, 0x1c000000: 0x84000, 0x1d000000: 0x40004000, 0x1e000000: 0x40000000, 0x1f000000: 0x40084010, 0x10800000: 0x84010, 0x11800000: 0x80000, 0x12800000: 0x40080000, 0x13800000: 0x4000, 0x14800000: 0x40004000, 0x15800000: 0x40084010, 0x16800000: 0x10, 0x17800000: 0x40000000, 0x18800000: 0x40084000, 0x19800000: 0x40000010, 0x1a800000: 0x40004010, 0x1b800000: 0x80010, 0x1c800000: 0x0, 0x1d800000: 0x4010, 0x1e800000: 0x40080010, 0x1f800000: 0x84000 }, { 0x0: 0x104, 0x100000: 0x0, 0x200000: 0x4000100, 0x300000: 0x10104, 0x400000: 0x10004, 0x500000: 0x4000004, 0x600000: 0x4010104, 0x700000: 0x4010000, 0x800000: 0x4000000, 0x900000: 0x4010100, 0xa00000: 0x10100, 0xb00000: 0x4010004, 0xc00000: 0x4000104, 0xd00000: 0x10000, 0xe00000: 0x4, 0xf00000: 0x100, 0x80000: 0x4010100, 0x180000: 0x4010004, 0x280000: 0x0, 0x380000: 0x4000100, 0x480000: 0x4000004, 0x580000: 0x10000, 0x680000: 0x10004, 0x780000: 0x104, 0x880000: 0x4, 0x980000: 0x100, 0xa80000: 0x4010000, 0xb80000: 0x10104, 0xc80000: 0x10100, 0xd80000: 0x4000104, 0xe80000: 0x4010104, 0xf80000: 0x4000000, 0x1000000: 0x4010100, 0x1100000: 0x10004, 0x1200000: 0x10000, 0x1300000: 0x4000100, 0x1400000: 0x100, 0x1500000: 0x4010104, 0x1600000: 0x4000004, 0x1700000: 0x0, 0x1800000: 0x4000104, 0x1900000: 0x4000000, 0x1a00000: 0x4, 0x1b00000: 0x10100, 0x1c00000: 0x4010000, 0x1d00000: 0x104, 0x1e00000: 0x10104, 0x1f00000: 0x4010004, 0x1080000: 0x4000000, 0x1180000: 0x104, 0x1280000: 0x4010100, 0x1380000: 0x0, 0x1480000: 0x10004, 0x1580000: 0x4000100, 0x1680000: 0x100, 0x1780000: 0x4010004, 0x1880000: 0x10000, 0x1980000: 0x4010104, 0x1a80000: 0x10104, 0x1b80000: 0x4000004, 0x1c80000: 0x4000104, 0x1d80000: 0x4010000, 0x1e80000: 0x4, 0x1f80000: 0x10100 }, { 0x0: 0x80401000, 0x10000: 0x80001040, 0x20000: 0x401040, 0x30000: 0x80400000, 0x40000: 0x0, 0x50000: 0x401000, 0x60000: 0x80000040, 0x70000: 0x400040, 0x80000: 0x80000000, 0x90000: 0x400000, 0xa0000: 0x40, 0xb0000: 0x80001000, 0xc0000: 0x80400040, 0xd0000: 0x1040, 0xe0000: 0x1000, 0xf0000: 0x80401040, 0x8000: 0x80001040, 0x18000: 0x40, 0x28000: 0x80400040, 0x38000: 0x80001000, 0x48000: 0x401000, 0x58000: 0x80401040, 0x68000: 0x0, 0x78000: 0x80400000, 0x88000: 0x1000, 0x98000: 0x80401000, 0xa8000: 0x400000, 0xb8000: 0x1040, 0xc8000: 0x80000000, 0xd8000: 0x400040, 0xe8000: 0x401040, 0xf8000: 0x80000040, 0x100000: 0x400040, 0x110000: 0x401000, 0x120000: 0x80000040, 0x130000: 0x0, 0x140000: 0x1040, 0x150000: 0x80400040, 0x160000: 0x80401000, 0x170000: 0x80001040, 0x180000: 0x80401040, 0x190000: 0x80000000, 0x1a0000: 0x80400000, 0x1b0000: 0x401040, 0x1c0000: 0x80001000, 0x1d0000: 0x400000, 0x1e0000: 0x40, 0x1f0000: 0x1000, 0x108000: 0x80400000, 0x118000: 0x80401040, 0x128000: 0x0, 0x138000: 0x401000, 0x148000: 0x400040, 0x158000: 0x80000000, 0x168000: 0x80001040, 0x178000: 0x40, 0x188000: 0x80000040, 0x198000: 0x1000, 0x1a8000: 0x80001000, 0x1b8000: 0x80400040, 0x1c8000: 0x1040, 0x1d8000: 0x80401000, 0x1e8000: 0x400000, 0x1f8000: 0x401040 }, { 0x0: 0x80, 0x1000: 0x1040000, 0x2000: 0x40000, 0x3000: 0x20000000, 0x4000: 0x20040080, 0x5000: 0x1000080, 0x6000: 0x21000080, 0x7000: 0x40080, 0x8000: 0x1000000, 0x9000: 0x20040000, 0xa000: 0x20000080, 0xb000: 0x21040080, 0xc000: 0x21040000, 0xd000: 0x0, 0xe000: 0x1040080, 0xf000: 0x21000000, 0x800: 0x1040080, 0x1800: 0x21000080, 0x2800: 0x80, 0x3800: 0x1040000, 0x4800: 0x40000, 0x5800: 0x20040080, 0x6800: 0x21040000, 0x7800: 0x20000000, 0x8800: 0x20040000, 0x9800: 0x0, 0xa800: 0x21040080, 0xb800: 0x1000080, 0xc800: 0x20000080, 0xd800: 0x21000000, 0xe800: 0x1000000, 0xf800: 0x40080, 0x10000: 0x40000, 0x11000: 0x80, 0x12000: 0x20000000, 0x13000: 0x21000080, 0x14000: 0x1000080, 0x15000: 0x21040000, 0x16000: 0x20040080, 0x17000: 0x1000000, 0x18000: 0x21040080, 0x19000: 0x21000000, 0x1a000: 0x1040000, 0x1b000: 0x20040000, 0x1c000: 0x40080, 0x1d000: 0x20000080, 0x1e000: 0x0, 0x1f000: 0x1040080, 0x10800: 0x21000080, 0x11800: 0x1000000, 0x12800: 0x1040000, 0x13800: 0x20040080, 0x14800: 0x20000000, 0x15800: 0x1040080, 0x16800: 0x80, 0x17800: 0x21040000, 0x18800: 0x40080, 0x19800: 0x21040080, 0x1a800: 0x0, 0x1b800: 0x21000000, 0x1c800: 0x1000080, 0x1d800: 0x40000, 0x1e800: 0x20040000, 0x1f800: 0x20000080 }, { 0x0: 0x10000008, 0x100: 0x2000, 0x200: 0x10200000, 0x300: 0x10202008, 0x400: 0x10002000, 0x500: 0x200000, 0x600: 0x200008, 0x700: 0x10000000, 0x800: 0x0, 0x900: 0x10002008, 0xa00: 0x202000, 0xb00: 0x8, 0xc00: 0x10200008, 0xd00: 0x202008, 0xe00: 0x2008, 0xf00: 0x10202000, 0x80: 0x10200000, 0x180: 0x10202008, 0x280: 0x8, 0x380: 0x200000, 0x480: 0x202008, 0x580: 0x10000008, 0x680: 0x10002000, 0x780: 0x2008, 0x880: 0x200008, 0x980: 0x2000, 0xa80: 0x10002008, 0xb80: 0x10200008, 0xc80: 0x0, 0xd80: 0x10202000, 0xe80: 0x202000, 0xf80: 0x10000000, 0x1000: 0x10002000, 0x1100: 0x10200008, 0x1200: 0x10202008, 0x1300: 0x2008, 0x1400: 0x200000, 0x1500: 0x10000000, 0x1600: 0x10000008, 0x1700: 0x202000, 0x1800: 0x202008, 0x1900: 0x0, 0x1a00: 0x8, 0x1b00: 0x10200000, 0x1c00: 0x2000, 0x1d00: 0x10002008, 0x1e00: 0x10202000, 0x1f00: 0x200008, 0x1080: 0x8, 0x1180: 0x202000, 0x1280: 0x200000, 0x1380: 0x10000008, 0x1480: 0x10002000, 0x1580: 0x2008, 0x1680: 0x10202008, 0x1780: 0x10200000, 0x1880: 0x10202000, 0x1980: 0x10200008, 0x1a80: 0x2000, 0x1b80: 0x202008, 0x1c80: 0x200008, 0x1d80: 0x0, 0x1e80: 0x10000000, 0x1f80: 0x10002008 }, { 0x0: 0x100000, 0x10: 0x2000401, 0x20: 0x400, 0x30: 0x100401, 0x40: 0x2100401, 0x50: 0x0, 0x60: 0x1, 0x70: 0x2100001, 0x80: 0x2000400, 0x90: 0x100001, 0xa0: 0x2000001, 0xb0: 0x2100400, 0xc0: 0x2100000, 0xd0: 0x401, 0xe0: 0x100400, 0xf0: 0x2000000, 0x8: 0x2100001, 0x18: 0x0, 0x28: 0x2000401, 0x38: 0x2100400, 0x48: 0x100000, 0x58: 0x2000001, 0x68: 0x2000000, 0x78: 0x401, 0x88: 0x100401, 0x98: 0x2000400, 0xa8: 0x2100000, 0xb8: 0x100001, 0xc8: 0x400, 0xd8: 0x2100401, 0xe8: 0x1, 0xf8: 0x100400, 0x100: 0x2000000, 0x110: 0x100000, 0x120: 0x2000401, 0x130: 0x2100001, 0x140: 0x100001, 0x150: 0x2000400, 0x160: 0x2100400, 0x170: 0x100401, 0x180: 0x401, 0x190: 0x2100401, 0x1a0: 0x100400, 0x1b0: 0x1, 0x1c0: 0x0, 0x1d0: 0x2100000, 0x1e0: 0x2000001, 0x1f0: 0x400, 0x108: 0x100400, 0x118: 0x2000401, 0x128: 0x2100001, 0x138: 0x1, 0x148: 0x2000000, 0x158: 0x100000, 0x168: 0x401, 0x178: 0x2100400, 0x188: 0x2000001, 0x198: 0x2100000, 0x1a8: 0x0, 0x1b8: 0x2100401, 0x1c8: 0x100401, 0x1d8: 0x400, 0x1e8: 0x2000400, 0x1f8: 0x100001 }, { 0x0: 0x8000820, 0x1: 0x20000, 0x2: 0x8000000, 0x3: 0x20, 0x4: 0x20020, 0x5: 0x8020820, 0x6: 0x8020800, 0x7: 0x800, 0x8: 0x8020000, 0x9: 0x8000800, 0xa: 0x20800, 0xb: 0x8020020, 0xc: 0x820, 0xd: 0x0, 0xe: 0x8000020, 0xf: 0x20820, 0x80000000: 0x800, 0x80000001: 0x8020820, 0x80000002: 0x8000820, 0x80000003: 0x8000000, 0x80000004: 0x8020000, 0x80000005: 0x20800, 0x80000006: 0x20820, 0x80000007: 0x20, 0x80000008: 0x8000020, 0x80000009: 0x820, 0x8000000a: 0x20020, 0x8000000b: 0x8020800, 0x8000000c: 0x0, 0x8000000d: 0x8020020, 0x8000000e: 0x8000800, 0x8000000f: 0x20000, 0x10: 0x20820, 0x11: 0x8020800, 0x12: 0x20, 0x13: 0x800, 0x14: 0x8000800, 0x15: 0x8000020, 0x16: 0x8020020, 0x17: 0x20000, 0x18: 0x0, 0x19: 0x20020, 0x1a: 0x8020000, 0x1b: 0x8000820, 0x1c: 0x8020820, 0x1d: 0x20800, 0x1e: 0x820, 0x1f: 0x8000000, 0x80000010: 0x20000, 0x80000011: 0x800, 0x80000012: 0x8020020, 0x80000013: 0x20820, 0x80000014: 0x20, 0x80000015: 0x8020000, 0x80000016: 0x8000000, 0x80000017: 0x8000820, 0x80000018: 0x8020820, 0x80000019: 0x8000020, 0x8000001a: 0x8000800, 0x8000001b: 0x0, 0x8000001c: 0x20800, 0x8000001d: 0x820, 0x8000001e: 0x20020, 0x8000001f: 0x8020800 } ]; // Masks that select the SBOX input var SBOX_MASK = [ 0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000, 0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f ]; /** * DES block cipher algorithm. */ var DES = C_algo.DES = BlockCipher.extend({ _doReset: function () { // Shortcuts var key = this._key; var keyWords = key.words; // Select 56 bits according to PC1 var keyBits = []; for (var i = 0; i < 56; i++) { var keyBitPos = PC1[i] - 1; keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1; } // Assemble 16 subkeys var subKeys = this._subKeys = []; for (var nSubKey = 0; nSubKey < 16; nSubKey++) { // Create subkey var subKey = subKeys[nSubKey] = []; // Shortcut var bitShift = BIT_SHIFTS[nSubKey]; // Select 48 bits according to PC2 for (var i = 0; i < 24; i++) { // Select from the left 28 key bits subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6); // Select from the right 28 key bits subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6); } // Since each subkey is applied to an expanded 32-bit input, // the subkey can be broken into 8 values scaled to 32-bits, // which allows the key to be used without expansion subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31); for (var i = 1; i < 7; i++) { subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3); } subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27); } // Compute inverse subkeys var invSubKeys = this._invSubKeys = []; for (var i = 0; i < 16; i++) { invSubKeys[i] = subKeys[15 - i]; } }, encryptBlock: function (M, offset) { this._doCryptBlock(M, offset, this._subKeys); }, decryptBlock: function (M, offset) { this._doCryptBlock(M, offset, this._invSubKeys); }, _doCryptBlock: function (M, offset, subKeys) { // Get input this._lBlock = M[offset]; this._rBlock = M[offset + 1]; // Initial permutation exchangeLR.call(this, 4, 0x0f0f0f0f); exchangeLR.call(this, 16, 0x0000ffff); exchangeRL.call(this, 2, 0x33333333); exchangeRL.call(this, 8, 0x00ff00ff); exchangeLR.call(this, 1, 0x55555555); // Rounds for (var round = 0; round < 16; round++) { // Shortcuts var subKey = subKeys[round]; var lBlock = this._lBlock; var rBlock = this._rBlock; // Feistel function var f = 0; for (var i = 0; i < 8; i++) { f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0]; } this._lBlock = rBlock; this._rBlock = lBlock ^ f; } // Undo swap from last round var t = this._lBlock; this._lBlock = this._rBlock; this._rBlock = t; // Final permutation exchangeLR.call(this, 1, 0x55555555); exchangeRL.call(this, 8, 0x00ff00ff); exchangeRL.call(this, 2, 0x33333333); exchangeLR.call(this, 16, 0x0000ffff); exchangeLR.call(this, 4, 0x0f0f0f0f); // Set output M[offset] = this._lBlock; M[offset + 1] = this._rBlock; }, keySize: 64/32, ivSize: 64/32, blockSize: 64/32 }); // Swap bits across the left and right words function exchangeLR(offset, mask) { var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask; this._rBlock ^= t; this._lBlock ^= t << offset; } function exchangeRL(offset, mask) { var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask; this._lBlock ^= t; this._rBlock ^= t << offset; } /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.DES.encrypt(message, key, cfg); * var plaintext = CryptoJS.DES.decrypt(ciphertext, key, cfg); */ C.DES = BlockCipher._createHelper(DES); /** * Triple-DES block cipher algorithm. */ var TripleDES = C_algo.TripleDES = BlockCipher.extend({ _doReset: function () { // Shortcuts var key = this._key; var keyWords = key.words; // Create DES instances this._des1 = DES.createEncryptor(WordArray.create(keyWords.slice(0, 2))); this._des2 = DES.createEncryptor(WordArray.create(keyWords.slice(2, 4))); this._des3 = DES.createEncryptor(WordArray.create(keyWords.slice(4, 6))); }, encryptBlock: function (M, offset) { this._des1.encryptBlock(M, offset); this._des2.decryptBlock(M, offset); this._des3.encryptBlock(M, offset); }, decryptBlock: function (M, offset) { this._des3.decryptBlock(M, offset); this._des2.encryptBlock(M, offset); this._des1.decryptBlock(M, offset); }, keySize: 192/32, ivSize: 64/32, blockSize: 64/32 }); /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg); * var plaintext = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg); */ C.TripleDES = BlockCipher._createHelper(TripleDES); }()); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var StreamCipher = C_lib.StreamCipher; var C_algo = C.algo; /** * RC4 stream cipher algorithm. */ var RC4 = C_algo.RC4 = StreamCipher.extend({ _doReset: function () { // Shortcuts var key = this._key; var keyWords = key.words; var keySigBytes = key.sigBytes; // Init sbox var S = this._S = []; for (var i = 0; i < 256; i++) { S[i] = i; } // Key setup for (var i = 0, j = 0; i < 256; i++) { var keyByteIndex = i % keySigBytes; var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff; j = (j + S[i] + keyByte) % 256; // Swap var t = S[i]; S[i] = S[j]; S[j] = t; } // Counters this._i = this._j = 0; }, _doProcessBlock: function (M, offset) { M[offset] ^= generateKeystreamWord.call(this); }, keySize: 256/32, ivSize: 0 }); function generateKeystreamWord() { // Shortcuts var S = this._S; var i = this._i; var j = this._j; // Generate keystream word var keystreamWord = 0; for (var n = 0; n < 4; n++) { i = (i + 1) % 256; j = (j + S[i]) % 256; // Swap var t = S[i]; S[i] = S[j]; S[j] = t; keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8); } // Update counters this._i = i; this._j = j; return keystreamWord; } /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg); * var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg); */ C.RC4 = StreamCipher._createHelper(RC4); /** * Modified RC4 stream cipher algorithm. */ var RC4Drop = C_algo.RC4Drop = RC4.extend({ /** * Configuration options. * * @property {number} drop The number of keystream words to drop. Default 192 */ cfg: RC4.cfg.extend({ drop: 192 }), _doReset: function () { RC4._doReset.call(this); // Drop for (var i = this.cfg.drop; i > 0; i--) { generateKeystreamWord.call(this); } } }); /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg); * var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg); */ C.RC4Drop = StreamCipher._createHelper(RC4Drop); }()); /** @preserve * Counter block mode compatible with Dr Brian Gladman fileenc.c * derived from CryptoJS.mode.CTR * Jan Hruby [email protected] */ CryptoJS.mode.CTRGladman = (function () { var CTRGladman = CryptoJS.lib.BlockCipherMode.extend(); function incWord(word) { if (((word >> 24) & 0xff) === 0xff) { //overflow var b1 = (word >> 16)&0xff; var b2 = (word >> 8)&0xff; var b3 = word & 0xff; if (b1 === 0xff) // overflow b1 { b1 = 0; if (b2 === 0xff) { b2 = 0; if (b3 === 0xff) { b3 = 0; } else { ++b3; } } else { ++b2; } } else { ++b1; } word = 0; word += (b1 << 16); word += (b2 << 8); word += b3; } else { word += (0x01 << 24); } return word; } function incCounter(counter) { if ((counter[0] = incWord(counter[0])) === 0) { // encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8 counter[1] = incWord(counter[1]); } return counter; } var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher var blockSize = cipher.blockSize; var iv = this._iv; var counter = this._counter; // Generate keystream if (iv) { counter = this._counter = iv.slice(0); // Remove IV for subsequent blocks this._iv = undefined; } incCounter(counter); var keystream = counter.slice(0); cipher.encryptBlock(keystream, 0); // Encrypt for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } }); CTRGladman.Decryptor = Encryptor; return CTRGladman; }()); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var StreamCipher = C_lib.StreamCipher; var C_algo = C.algo; // Reusable objects var S = []; var C_ = []; var G = []; /** * Rabbit stream cipher algorithm */ var Rabbit = C_algo.Rabbit = StreamCipher.extend({ _doReset: function () { // Shortcuts var K = this._key.words; var iv = this.cfg.iv; // Swap endian for (var i = 0; i < 4; i++) { K[i] = (((K[i] << 8) | (K[i] >>> 24)) & 0x00ff00ff) | (((K[i] << 24) | (K[i] >>> 8)) & 0xff00ff00); } // Generate initial state values var X = this._X = [ K[0], (K[3] << 16) | (K[2] >>> 16), K[1], (K[0] << 16) | (K[3] >>> 16), K[2], (K[1] << 16) | (K[0] >>> 16), K[3], (K[2] << 16) | (K[1] >>> 16) ]; // Generate initial counter values var C = this._C = [ (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff), (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff), (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff), (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff) ]; // Carry bit this._b = 0; // Iterate the system four times for (var i = 0; i < 4; i++) { nextState.call(this); } // Modify the counters for (var i = 0; i < 8; i++) { C[i] ^= X[(i + 4) & 7]; } // IV setup if (iv) { // Shortcuts var IV = iv.words; var IV_0 = IV[0]; var IV_1 = IV[1]; // Generate four subvectors var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00); var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00); var i1 = (i0 >>> 16) | (i2 & 0xffff0000); var i3 = (i2 << 16) | (i0 & 0x0000ffff); // Modify counter values C[0] ^= i0; C[1] ^= i1; C[2] ^= i2; C[3] ^= i3; C[4] ^= i0; C[5] ^= i1; C[6] ^= i2; C[7] ^= i3; // Iterate the system four times for (var i = 0; i < 4; i++) { nextState.call(this); } } }, _doProcessBlock: function (M, offset) { // Shortcut var X = this._X; // Iterate the system nextState.call(this); // Generate four keystream words S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16); S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16); S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16); S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16); for (var i = 0; i < 4; i++) { // Swap endian S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) | (((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00); // Encrypt M[offset + i] ^= S[i]; } }, blockSize: 128/32, ivSize: 64/32 }); function nextState() { // Shortcuts var X = this._X; var C = this._C; // Save old counter values for (var i = 0; i < 8; i++) { C_[i] = C[i]; } // Calculate new counter values C[0] = (C[0] + 0x4d34d34d + this._b) | 0; C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0; C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0; C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0; C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0; C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0; C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0; C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0; this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0; // Calculate the g-values for (var i = 0; i < 8; i++) { var gx = X[i] + C[i]; // Construct high and low argument for squaring var ga = gx & 0xffff; var gb = gx >>> 16; // Calculate high and low result of squaring var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb; var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0); // High XOR low G[i] = gh ^ gl; } // Calculate new state values X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0; X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0; X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0; X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0; X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0; X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0; X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0; X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0; } /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg); * var plaintext = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg); */ C.Rabbit = StreamCipher._createHelper(Rabbit); }()); /** * Counter block mode. */ CryptoJS.mode.CTR = (function () { var CTR = CryptoJS.lib.BlockCipherMode.extend(); var Encryptor = CTR.Encryptor = CTR.extend({ processBlock: function (words, offset) { // Shortcuts var cipher = this._cipher var blockSize = cipher.blockSize; var iv = this._iv; var counter = this._counter; // Generate keystream if (iv) { counter = this._counter = iv.slice(0); // Remove IV for subsequent blocks this._iv = undefined; } var keystream = counter.slice(0); cipher.encryptBlock(keystream, 0); // Increment counter counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0 // Encrypt for (var i = 0; i < blockSize; i++) { words[offset + i] ^= keystream[i]; } } }); CTR.Decryptor = Encryptor; return CTR; }()); (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var StreamCipher = C_lib.StreamCipher; var C_algo = C.algo; // Reusable objects var S = []; var C_ = []; var G = []; /** * Rabbit stream cipher algorithm. * * This is a legacy version that neglected to convert the key to little-endian. * This error doesn't affect the cipher's security, * but it does affect its compatibility with other implementations. */ var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({ _doReset: function () { // Shortcuts var K = this._key.words; var iv = this.cfg.iv; // Generate initial state values var X = this._X = [ K[0], (K[3] << 16) | (K[2] >>> 16), K[1], (K[0] << 16) | (K[3] >>> 16), K[2], (K[1] << 16) | (K[0] >>> 16), K[3], (K[2] << 16) | (K[1] >>> 16) ]; // Generate initial counter values var C = this._C = [ (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff), (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff), (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff), (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff) ]; // Carry bit this._b = 0; // Iterate the system four times for (var i = 0; i < 4; i++) { nextState.call(this); } // Modify the counters for (var i = 0; i < 8; i++) { C[i] ^= X[(i + 4) & 7]; } // IV setup if (iv) { // Shortcuts var IV = iv.words; var IV_0 = IV[0]; var IV_1 = IV[1]; // Generate four subvectors var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00); var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00); var i1 = (i0 >>> 16) | (i2 & 0xffff0000); var i3 = (i2 << 16) | (i0 & 0x0000ffff); // Modify counter values C[0] ^= i0; C[1] ^= i1; C[2] ^= i2; C[3] ^= i3; C[4] ^= i0; C[5] ^= i1; C[6] ^= i2; C[7] ^= i3; // Iterate the system four times for (var i = 0; i < 4; i++) { nextState.call(this); } } }, _doProcessBlock: function (M, offset) { // Shortcut var X = this._X; // Iterate the system nextState.call(this); // Generate four keystream words S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16); S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16); S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16); S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16); for (var i = 0; i < 4; i++) { // Swap endian S[i] = (((S[i] << 8) | (S[i] >>> 24)) & 0x00ff00ff) | (((S[i] << 24) | (S[i] >>> 8)) & 0xff00ff00); // Encrypt M[offset + i] ^= S[i]; } }, blockSize: 128/32, ivSize: 64/32 }); function nextState() { // Shortcuts var X = this._X; var C = this._C; // Save old counter values for (var i = 0; i < 8; i++) { C_[i] = C[i]; } // Calculate new counter values C[0] = (C[0] + 0x4d34d34d + this._b) | 0; C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0; C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0; C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0; C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0; C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0; C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0; C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0; this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0; // Calculate the g-values for (var i = 0; i < 8; i++) { var gx = X[i] + C[i]; // Construct high and low argument for squaring var ga = gx & 0xffff; var gb = gx >>> 16; // Calculate high and low result of squaring var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb; var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0); // High XOR low G[i] = gh ^ gl; } // Calculate new state values X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0; X[1] = (G[1] + ((G[0] << 8) | (G[0] >>> 24)) + G[7]) | 0; X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0; X[3] = (G[3] + ((G[2] << 8) | (G[2] >>> 24)) + G[1]) | 0; X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0; X[5] = (G[5] + ((G[4] << 8) | (G[4] >>> 24)) + G[3]) | 0; X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0; X[7] = (G[7] + ((G[6] << 8) | (G[6] >>> 24)) + G[5]) | 0; } /** * Shortcut functions to the cipher's object interface. * * @example * * var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg); * var plaintext = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg); */ C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy); }()); /** * Zero padding strategy. */ CryptoJS.pad.ZeroPadding = { pad: function (data, blockSize) { // Shortcut var blockSizeBytes = blockSize * 4; // Pad data.clamp(); data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes); }, unpad: function (data) { // Shortcut var dataWords = data.words; // Unpad var i = data.sigBytes - 1; while (!((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) { i--; } data.sigBytes = i + 1; } }; return CryptoJS; })); /** * Decrypt a salted msg using a password. * Inspired by https://github.com/adonespitogo */ var keySize = 256; var iterations = 1000; function decrypt (encryptedMsg, pass) { var salt = CryptoJS.enc.Hex.parse(encryptedMsg.substr(0, 32)); var iv = CryptoJS.enc.Hex.parse(encryptedMsg.substr(32, 32)) var encrypted = encryptedMsg.substring(64); var key = CryptoJS.PBKDF2(pass, salt, { keySize: keySize/32, iterations: iterations }); var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }).toString(CryptoJS.enc.Utf8); return decrypted; } document.getElementById('staticrypt-form').addEventListener('submit', function(e) { e.preventDefault(); var passphrase = document.getElementById('staticrypt-password').value, encryptedMsg = '2daa6798054d8a429fa3c5e36aea2cdc03377a334f45ddb047851f4018e17c1554e032e4af28926594db83aa38e07f724a1e55a44ddd7f734d0cd45a6614fd4evv0ouOnc7U1z07C1+5TyS8jmwEpngQgO/mptv2/bukMMAeD40gyCLUBm+I6gcHsM0UR7O4S3sEzQZwwfVD6LboVmQsbyhmCJ5hgKULWqFWOkq9dCNMvkGMo+6ZH7VwRB1pD3rIz1cJvIGJcNhVeOFfj2Aa4wscfAa45+FmGSfMTWqde94qkApCVUTV6qp3Oi+TKE6IOMfDocNpHQ+nLt38+azGxzs03cbGARQZ+kXzgdwdAWdhxFEe+tFcUDd4CtGP9gJMyeI0cZeI7hbuz92zz0qrwGkf0MlN92BXxBMsoA5vsvOoVxQF8UmsbVFF0nO9W/wY/dx3abYf95+jGNEozG73Osh1YH+/e2mQ4pCuQ=', encryptedHMAC = encryptedMsg.substring(0, 64), encryptedHTML = encryptedMsg.substring(64), decryptedHMAC = CryptoJS.HmacSHA256(encryptedHTML, CryptoJS.SHA256(passphrase).toString()).toString(); if (decryptedHMAC !== encryptedHMAC) { alert('Bad passphrase!'); return; } var plainHTML = decrypt(encryptedHTML, passphrase); document.write(plainHTML); document.close(); });
0 notes
chennee26 · 4 years ago
Text
Simplify Static Asset Management With Vue.js Single-File Component
Tumblr media
Static asset management is one of the more painful and mysterious challenges front-end developers face. We want our source code to be simple to develop and maintain, but we rely on browsers to be lean and mean. Browsers can’t be expected to understand our fancy source files with conveniences like Sass or the newest bleeding edge JavaScript features. We configure transpilers, linters, and compressors that watch for source code changes or get triggered by build processes. And finally, these tools emit static assets that a browser can interpret
Tumblr media
Even when we don’t use fancy preprocessors, we still copy the source files to a dist directory to deploy them…because…well…it’s just what we do!
Tumblr media
On top of this complexity, we have traditionally maintained a separation of concerns between markup, scripting, and styling. This separation can lead to extreme bloat that makes our applications difficult to maintain.
Imagine a request to remove a component from a view. You remove the markup…but can you track down CSS selectors that are specific to this component? All the media queries? Do you feel safe removing code that may affect other parts of the view? What about a request to modify a component’s appearance? Do you add a new class to your updated component and leave the old styling behind, just in case there are other parts of the view that are styled by it? Technical debt accumulates. Eventually, you have a pile of dead code mixed in with the good stuff. It’s very difficult to clean up, and nobody wants to pay for the effort.
Tumblr media
Not to imply that your code is inherently bad. It’s a consequence of the separation of concerns that has made the internet look sharp since the W3C adopted CSS in 1996.
So, what are our alternatives? Inline CSS? An occasional inline style attribute is acceptable in the 21st century. But even with CSS-in-JS libraries, this solution can be challenging to scale. We need the cascade. We need media queries.
Many modern frameworks combine JavaScript with markup; it’s the core of the React, Angular, and Vue.js revolution. The concept of “styled components” is also trending. But unification usually comes at a cost. The learning curve, awkward code structure, and dependency on 3rd party libraries may outweigh the advantages. However, Vue’s out-of-the-box support for the concept makes it simple to grasp and implement.
Tumblr media
The Vue.js framework Single-File Component (SFC) allows you to combine templating, scripting, and styling in a single source file that can accept props and manage state. Vue CLI — the “beginner” installation of Vue.js — will pre-configure the bridge between your .vue source files and webpack that requires absolutely no configuration or webpack knowledge. Let’s open a terminal and quickly build a working example using npm.
1.Install Vue CLI: npm install -g @vue/cli
2.Create a new project (accept the default settings): vue create vue-sfc-example
3.Start the project: npm run serve
4. Render HelloWorld.vue in a browser: http://localhost:8080
Tumblr media
SO easy. Let’s open the source to see what we built.
<template>
<div class="hello">
...some markup...
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
The <template> tag wraps Vue template syntax enhanced markup.
The <script> tag wraps JavaScript.
The <style> tag wraps CSS.
Aside from placing the styling at the end of the file, this source file looks an awful lot like an html file that a browser could interpret. There is a lot going on under the hood, but Vue doesn’t clutter the source with tooling bloat.
Let’s concentrate on the <style> tag. The boilerplate contains some basic CSS, and an attribute named “scoped”. As the code comment implies, this attribute allows you to “scope” this block to only apply to this particular component, by automatically namespacing the CSS. Compare this to a more traditional approach, which might involve creating a selector like: “#hello-world-component-namespace.this-component {...}” in some faraway css file. The scoped attribute is optional. If you want to modify child components, one approach is to exclude the scoped attribute. You may also use multiple blocks of CSS, in case you wish to scope part of the code, but style children with a separate CSS block.
<style scoped>
h3 {
margin: 40px 0 0;
}
...
</style>
<style>
#child-component > h3 {
margin: 10px;
}
...
</style>
If you inspect the source code in your browser, you can see this style block rendered in the head of the document:
<style type="text/css">h3[data-v-469af010] {
margin: 40px 0 0;
}
ul[data-v-469af010] {
list-style-type: none;
padding: 0;
}
li[data-v-469af010] {
display: inline-block;
margin: 0 10px;
}
a[data-v-469af010] {
color: #42b983;
}
</style>
There is no need to version or deploy a CSS file, in this example. The data attribute in the first block is no accident. It uniquely identifies the component this styling is scoped to.
<div data-v-469af010="" class="hello">...</div>
Predictably, namespacing is suppressed for code blocks that are not scoped.
<style type="text/css">
#child-component > h3 {
margin: 10px;
}
</style>
An alternative to this approach is the ::v-deep combinator, which allows you to style children from a scoped block. Details can be found here.
But what about my Sass? Good news: SFCs tap into all of your favorite webpack preprocessors. Install sass-loader with npm:
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
> li {
display: inline-block;
margin: 0 10px;
a {
color: #42b983;
&amp;.very-green {
#00ff00;
}
}
}
}
</style>
But what about my Sass globals, includes, mixins, etc.? Never fear — the Sass block you include in your SFCs works just like your typical Sass source file. You can pass includes, set variables, nest media queries, and any other Sass convenience.
<style scoped lang="scss">
@import "mixins";
@import "global/global";
#main {
padding-top: em(54);
@media (min-width: $screen-md) {
padding-top: 0;
}
}
</style>
The vue-loader, which is included and pre-configured by Vue CLI, makes all of this work. Sass/Scss, Less, Babel, TypeScript, and other popular preprocessors and linters are supported. These features can be discretely configured, to the delight of advanced users.
The Vue.js SFC offers the convenience our source code deserves, without the file management and webpack tooling headaches. You can also use the component state to set class and style inside your templates, using built-in lifecycle hooks. It is also important to note that you can still include CSS the typical way, or in a mixed mode. This is especially handy when using rapid prototyping libraries like Bootstrap.
What’s the catch? Vue.js is a relatively new player. It’s picking up steam, but there aren’t as many applications using the framework as the competing products — Angular and React. That means the user community is comparably small. Examples are slim and basic. You are cutting your own trail. Also, we have detected some “spookiness” in the way preprocessors react to code structure. The preprocessors may need some configuration and babysitting, once you scale into a larger project.
_________________________________________
0 notes
midseo · 4 months ago
Text
Sampling Booths, Sampling Booth Manufacturer, Sampling Booth Supplier
Sampling Booth : We are Sampling Booth Manufacturer, Sampling Booth Supplier, Sampling Booth in Munbai. Call Now.
Sampling Booths, Cleanroom Turnkey Project, Air Handling Unit, HVAC Ducting, HVAC Terminal Box, Electric Control Panel for AHU, Epoxy & Coving, Clean Room PUF Partition, Clean Room Door, Cleanroom Equipment, Dispensing Booth, Sampling Booth, Laminar Air Flow, Horizontal Laminar Air Flow, Vertical Laminar Air Flow, Mobile Trolley Laminar Air Flow, Laminar Air Flow for Operation Theatres, Static Pass Box, Dynamic Pass Box (2 Way),(3 Way), Biosafety Cabinet Class - II A2, Biosafety Cabinet Class - II B2, Static Garment Cubical, Dynamic Garment Cubical, Single Door Air Shower (2 Way), Double Door Air Shower (2 Way), HVAC Filters, Pre Filter, Fine Filter, Absolute HEPA Filter, Super HEPA Filter, Activated Carbon Filter, Miniplast HEPA Filter (Gasket), Miniplast HEPA Filter (Gel Seal), Combination Filter, Pocket Filter, Bag Filter, Modular Furniture, Modular Operation Theatre.
0 notes
mbaljeetsingh · 5 years ago
Text
Building a Blog with Next.js
In this article, we will use Next.js to build a static blog framework with the design and structure inspired by Jekyll. I’ve always been a big fan of how Jekyll makes it easier for beginners to setup a blog and at the same time also provides a great degree of control over every aspect of the blog for the advanced users.
With the introduction of Next.js in recent years, combined with the popularity of React, there is a new avenue to explore for static blogs. Next.js makes it super easy to build static websites based on the file system itself with little to no configuration required.
The directory structure of a typical bare-bones Jekyll blog looks like this:
. ├─── _posts/          ...blog posts in markdown ├─── _layouts/        ...layouts for different pages ├─── _includes/       ...re-usable components ├─── index.md         ...homepage └─── config.yml       ...blog config
The idea is to design our framework around this directory structure as much as possible so that it becomes easier to  migrate a blog from Jekyll by simply reusing the posts and configs defined in the blog.
For those unfamiliar with Jekyll, it is a static site generator that can transform your plain text into static websites and blogs. Refer the quick start guide to get up and running with Jekyll. This article also assumes that you have a basic knowledge of React. If not, React’s getting started page is a good place to start.
Installation
Next.js is powered by React and written in Node.js. So we need to install npm first, before adding next, react and react-dom to the project.
mkdir nextjs-blog && cd $_ npm init -y npm install next react react-dom --save
To run Next.js scripts on the command line, we have to add the next command to the scripts section of our package.json.
"scripts": {   "dev": "next" }
We can now run npm run dev on the command line for the first time. Let’s see what happens.
$ npm run dev > [email protected] dev /~user/nextjs-blog > next ready - started server on http://localhost:3000 Error: > Couldn't find a `pages` directory. Please create one under the project root
The compiler is complaining about a missing pages directory in the root of the project. We’ll learn about the concept of pages in the next section.
Concept of pages
Next.js is built around the concept of pages. Each page is a React component that can be of type .js or .jsx which is mapped to a route based on the filename. For example:
File                            Route ----                            ----- /pages/about.js                 /about /pages/projects/work1.js        /projects/work1 /pages/index.js                 /
Let’s create the pages directory in the root of the project and populate our first page, index.js, with a basic React component.
// pages/index.js export default function Blog() {   return <div>Welcome to the Next.js blog</div> }
Run npm run dev once again to start the server and navigate to http://localhost:3000 in the browser to view your blog for the first time.
Tumblr media
Out of the box, we get:
Hot reloading so we don’t have to refresh the browser for every code change.
Static generation of all pages inside the /pages/** directory.
Static file serving for assets living in the/public/** directory.
404 error page.
Navigate to a random path on localhost to see the 404 page in action. If you need a custom 404 page, the Next.js docs have great information.
Tumblr media
Dynamic pages
Pages with static routes are useful to build the homepage, about page, etc. However, to dynamically build all our posts, we will use the dynamic route capability of Next.js. For example:
File                        Route ----                        ----- /pages/posts/[slug].js      /posts/1                             /posts/abc                             /posts/hello-world
Any route, like /posts/1, /posts/abc, etc., will be matched by /posts/[slug].js and the slug parameter will be sent as a query parameter to the page. This is especially useful for our blog posts because we don’t want to create one file per post; instead we could dynamically pass the slug to render the corresponding post.
Anatomy of a blog
Now, since we understand the basic building blocks of Next.js, let’s define the anatomy of our blog.
. ├─ api │  └─ index.js             # fetch posts, load configs, parse .md files etc ├─ _includes │  ├─ footer.js            # footer component │  └─ header.js            # header component ├─ _layouts │  ├─ default.js           # default layout for static pages like index, about │  └─ post.js              # post layout inherts from the default layout ├─ pages │  ├─ index.js             # homepage |  └─ posts                # posts will be available on the route /posts/ |     └─ [slug].js       # dynamic page to build posts └─ _posts    ├─ welcome-to-nextjs.md    └─ style-guide-101.md
Blog API
A basic blog framework needs two API functions: 
A function to fetch the metadata of all the posts in _posts directory
A function to fetch a single post for a given slug with the complete HTML and metadata
Optionally, we would also like all the site’s configuration defined in config.yml to be available across all the components. So we need a function that will parse the YAML config into a native object.
Since, we would be dealing with a lot of non-JavaScript files, like Markdown (.md), YAML (.yml), etc, we’ll use the raw-loader library to load such files as strings to make it easier to process them. 
npm install raw-loader --save-dev
Next we need to tell Next.js to use raw-loader when we import .md and .yml file formats by creating a next.config.js file in the root of the project (more info on that).
module.exports = {   target: 'serverless',   webpack: function (config) {     config.module.rules.push({test:  /\.md$/, use: 'raw-loader'})     config.module.rules.push({test: /\.yml$/, use: 'raw-loader'})     return config   } }
Next.js 9.4 introduced aliases for relative imports which helps clean up the import statement spaghetti caused by relative paths. To use aliases, create a jsconfig.json file in the project’s root directory specifying the base path and all the module aliases needed for the project.
{   "compilerOptions": {     "baseUrl": "./",     "paths": {       "@includes/*": ["_includes/*"],       "@layouts/*": ["_layouts/*"],       "@posts/*": ["_posts/*"],       "@api": ["api/index"],     }   } }
For example, this allows us to import our layouts by just using:
import DefaultLayout from '@layouts/default'
Fetch all the posts
This function will read all the Markdown files in the _posts directory, parse the front matter defined at the beginning of the post using gray-matter and return the array of metadata for all the posts.
// api/index.js import matter from 'gray-matter' 
 export async function getAllPosts() {   const context = require.context('../_posts', false, /\.md$/)   const posts = []   for(const key of context.keys()){     const post = key.slice(2);     const content = await import(`../_posts/${post}`);     const meta = matter(content.default)     posts.push({       slug: post.replace('.md',''),       title: meta.data.title     })   }   return posts; }
A typical Markdown post looks like this:
--- title:  "Welcome to Next.js blog!" --- **Hello world**, this is my first Next.js blog post and it is written in Markdown. I hope you like it!
The section outlined by --- is called the front matter which holds the metadata of the post like, title, permalink, tags, etc. Here’s the output:
[   { slug: 'style-guide-101', title: 'Style Guide 101' },   { slug: 'welcome-to-nextjs', title: 'Welcome to Next.js blog!' } ]
Make sure you install the gray-matter library from npm first using the command npm install gray-matter --save-dev.
Fetch a single post
For a given slug, this function will locate the file in the _posts directory, parse the Markdown with the marked library and return the output HTML with metadata.
// api/index.js import matter from 'gray-matter' import marked from 'marked' 
 export async function getPostBySlug(slug) {   const fileContent = await import(`../_posts/${slug}.md`)   const meta = matter(fileContent.default)   const content = marked(meta.content)       return {     title: meta.data.title,      content: content   } }
Sample output:
{   title: 'Style Guide 101',   content: '<p>Incididunt cupidatat eiusmod ...</p>' }
Make sure you install the marked library from npm first using the command npm install marked --save-dev.
Config
In order to re-use the Jekyll config for our Next.js blog, we’ll parse the YAML file using the js-yaml library and export this config so that it can be used across components.
// config.yml title: "Next.js blog" description: "This blog is powered by Next.js" 
 // api/index.js import yaml from 'js-yaml' export async function getConfig() {   const config = await import(`../config.yml`)   return yaml.safeLoad(config.default) }
Make sure you install js-yaml from npm first using the command npm install js-yaml --save-dev.
Includes
Our _includes directory contains two basic React components, <Header> and <Footer>, which will be used in the different layout components defined in the _layouts directory.
// _includes/header.js export default function Header() {   return <header><p>Blog | Powered by Next.js</p></header> } 
 // _includes/footer.js export default function Footer() {   return <footer><p>©2020 | Footer</p></footer> }
Layouts
We have two layout components in the _layouts directory. One is the <DefaultLayout> which is the base layout on top of which every other layout component will be built.
// _layouts/default.js import Head from 'next/head' import Header from '@includes/header' import Footer from '@includes/footer' 
 export default function DefaultLayout(props) {   return (     <main>       <Head>         <title>{props.title}</title>         <meta name='description' content={props.description}/>       </Head>       <Header/>       {props.children}       <Footer/>     </main>   ) }
The second layout is the <PostLayout> component that will override the title defined in the <DefaultLayout> with the post title and render the HTML of the post. It also includes a link back to the homepage.
// _layouts/post.js import DefaultLayout from '@layouts/default' import Head from 'next/head' import Link from 'next/link' 
 export default function PostLayout(props) {   return (     <DefaultLayout>       <Head>         <title>{props.title}</title>       </Head>       <article>         <h1>{props.title}</h1>         <div dangerouslySetInnerHTML=/>         <div><Link href='/'><a>Home</a></Link></div>        </article>     </DefaultLayout>   ) }
next/head is a built-in component to append elements to the <head> of the page. next/link is a built-in component that handles client-side transitions between the routes defined in the pages directory.
Homepage
As part of the index page, aka homepage, we will list all the posts inside the _posts directory. The list will contain the post title and the permalink to the individual post page. The index page will use the <DefaultLayout> and we’ll import the config in the homepage to pass the title and description to the layout.
// pages/index.js import DefaultLayout from '@layouts/default' import Link from 'next/link' import { getConfig, getAllPosts } from '@api' 
 export default function Blog(props) {   return (     <DefaultLayout title={props.title} description={props.description}>       <p>List of posts:</p>       <ul>         {props.posts.map(function(post, idx) {           return (             <li key={idx}>               <Link href={'/posts/'+post.slug}>                 <a>{post.title}</a>               </Link>             </li>           )         })}       </ul>     </DefaultLayout>   ) }  
 export async function getStaticProps() {   const config = await getConfig()   const allPosts = await getAllPosts()   return {     props: {       posts: allPosts,       title: config.title,       description: config.description     }   } }
getStaticProps is called at the build time to pre-render pages by passing props to the default component of the page. We use this function to fetch the list of all posts at build time and render the posts archive on the homepage.
Tumblr media
Post page
This page will render the title and contents of the post for the slug supplied as part of the context. The post page will use the <PostLayout> component.
// pages/posts/[slug].js import PostLayout from '@layouts/post' import { getPostBySlug, getAllPosts } from "@api" 
 export default function Post(props) {   return <PostLayout title={props.title} content={props.content}/> } 
 export async function getStaticProps(context) {   return {     props: await getPostBySlug(context.params.slug)   } } 
 export async function getStaticPaths() {   let paths = await getAllPosts()   paths = paths.map(post => ({     params: { slug:post.slug }   }));   return {     paths: paths,     fallback: false   } }
If a page has dynamic routes, Next.js needs to know all the possible paths at build time. getStaticPaths supplies the list of paths that has to be rendered to HTML at build time. The fallback property ensures that if you visit a route that does not exist in the list of paths, it will return a 404 page.
Tumblr media
Production ready
Add the following commands for build and start in package.json, under the scripts section and then run npm run build followed by npm run start to build the static blog and start the production server.
// package.json "scripts": {   "dev": "next",   "build": "next build",   "start": "next start" }
The entire source code in this article is available on this GitHub repository. Feel free to clone it locally and play around with it. The repository also includes some basic placeholders to apply CSS to your blog.
Improvements
The blog, although functional, is perhaps too basic for most average cases. It would be nice to extend the framework or submit a patch to include some more features like:
Pagination
Syntax highlighting
Categories and Tags for posts
Styling
Overall, Next.js seems really very promising to build static websites, like a blog. Combined with its ability to export static HTML, we can built a truly standalone app without the need of a server!
The post Building a Blog with Next.js appeared first on CSS-Tricks.
via CSS-Tricks https://ift.tt/38RTO6t
0 notes
techcrunchappcom · 5 years ago
Photo
Tumblr media
New Post has been published on https://techcrunchapp.com/tiger-woods-film-headlines-new-sky-documentaries-channel-news-news/
Tiger Woods film headlines new Sky Documentaries channel | News News
Tumblr media Tumblr media Tumblr media
0:30
Don’t miss our special Tiger Woods documentary at 9pm on June 5
Don’t miss our special Tiger Woods documentary at 9pm on June 5
As fans anticipate the return of live sport, Sky is set to offer TV customers access to a selection of popular sporting documentaries via the brand new Sky Documentaries service, available on Sky Sports and NOW TV.
Among the diverse line-up is the brand new Sky Original documentary, Tiger Woods: Back. Based on the story of one of sport’s greatest ever comebacks, the documentary takes an in-depth look into the golfer’s 2019 Masters victory with never-before-seen footage from the Sky Sports archive.
There’s also exclusive interviews with golf legend Butch Harmon, Sir Nick Faldo, Jaime Diaz, Notah Begay III, Ewen Murray and Consultant Neurological Spinal Surgeon Mr Peter Hamlyn. Tiger Woods: Back will air at 9pm on June 5 on Sky Documentaries.
Other sporting documentaries, including two brand new Sky original commissions, available on the new Sky Documentaries service are; Busby, Ali & Cavett: The Tale of the Tapes, The Armstrong Lie, Women of Troy, Kevin Pietersen: Story of a Genius, Ferrari Race to Immortality, Kenny and more…
Sports fans eagerly awaiting the return of sport in the United Kingdom can also enjoy a different classic documentary each week on Sky Sports. The selection available to Sky Sports subscribers covers a variety of sports including; football’s ‘Life Of Ryan: Caretaker Manager’ and ’89’, to boxing’s ‘Klitschko’ and ‘I Am Ali’ and athletics’ ‘I Am Bolt’.
All documentaries on Sky Documentaries (Sky channel 114) and Sky Sports will be made available to Sky TV and NOW TV customers On Demand.
KEY SPORTING DOCUMENTARIES ON SKY
Available on Sky Documentaries
Tumblr media
A new Tiger Woods documentary chronicles his remarkable 2019 Masters victory at Augusta
Tiger Woods: Back
9pm, Friday June 5, Sky Documentaries and NOW TV
A Sky original documentary telling the incredible story of one of sports’ greatest ever comebacks. After undergoing four potentially career-ending back surgeries and having confessed that he may never play competitive golf again, Tiger Woods returned to Augusta, scene of his first Major triumph 22 years before, to confound his critics by dramatically winning his fifth Masters, his 15th Major and his own personal battle with his mind, his body and with the sport itself.
Busby
9pm, Thursday May 28, Sky Documentaries and NOW TV
The truly remarkable story of a Manchester United icon and one of the greatest football managers of all time. During 25 years in charge of Manchester United, his charisma, vision and steel revolutionised the beautiful game, turning Manchester United from the second-best team in their home city into one of the most iconic names in sport.
Ali & Cavett: The Tale of the Tapes
9pm, Friday May 29, Sky Documentaries and NOW TV
A vibrant portrait of boxing legend Muhammad Ali told through the lens of his frequent appearances on the Emmy Award-winning Dick Cavett Show. With natural charm, quick wit and playful pugnacity, Ali was a perfect foil for the sophisticated broadcast host, and together they struck television gold.
The Armstrong Lie
Available from May 27 on Sky Documentaries and NOW TV
Lance Armstrong was considered one of the greatest sports figures of all time after beating cancer and winning the Tour de France seven times. When Armstrong admitted to doping in 2012, USADA’s CEO, Travis Tygart, concluded that Armstrong’s team had run ‘the most sophisticated, professionalised and successful doping program that sport has ever seen’.
Women of Troy
Available from May 27 on Sky Documentaries and NOW TV
Women of Troy is a documentary film highlighting the historic and ground-breaking USC women’s basketball team of the 1980s, whose talent and charisma created new possibilities for women in basketball and helped paved the way for the WNBA.
Kevin Pietersen: Story of a Genius
Available from May 27 on Sky Documentaries and NOW TV
This documentary underlines the story of one of England’s most controversial and successful cricket players of all time. In this five-part documentary series, a group of cricket experts, ex-players and ex-coaches, along with Kevin himself, explain the fascinating and eventful life that the cricketer experienced.
Ferrari Race to Immortality
Available from May 27 on Sky Documentaries and NOW TV
Ferrari: Race to Immortality tells the story of the loves and losses, triumphs and tragedy of Ferrari’s most celebrated drivers in an era where they lived la dolce vita during the week, and it was win or die on any given Sunday.
Kenny
Available from May 27 on Sky Documentaries and NOW TV
The day after the Heysel disaster, Kenny Dalglish became manager of Liverpool Football Club. Six years later he resigned from the club, shell-shocked in the wake of the Hillsborough disaster. In between he created one of the most exciting football teams of all time. ‘Kenny’ explores more than just the roller-coaster career of an iconic footballer and manager.
New Commissions
Available later this year on Sky Documentaries and NOW TV
Tyson Bruno
This historic feature-length film charts the sensational highs and lows of two of the world’s most iconic black sportsmen. One hero, one villain: this is the story of America’s ‘baddest man on the planet’ Iron Mike Tyson as the friend and enemy of Britain’s gentle giant, Frank Bruno and the fascinating story of the way their lives remained connected like two sides of the same coin.
The United Way
The story of Manchester United is one of the ultimate stories of our time and it has never been fully told this way before, this documentary is led by the legendary Eric Cantona, who provides the creative and storytelling spine throughout the film. Think ‘Rome’ but in the sphere of sport – Old Trafford the Colosseum, titanic managers Sir Alex Ferguson and Sir Matt Busby the Emperors.
Available on Sky Sports
I Am Bolt
10pm, Tuesday May 26, Sky Sports Main Event, Sky Sports Arena and NOW TV
Watch Usain Bolt do what he does best as the Jamaican sprint legend – and the world’s fastest man – aims to make history at the 2016 Olympic Games in Rio with wins in both the 100m and 200m finals. The film looks into Bolt’s meteoric rise to sprinting supremacy. The rest is history…
Conor McGregor: Notorious
10pm, Tuesday June 2, Sky Sports Main Event, Sky Sports Action and NOW TV
A man synonymous with MMA fighting, watch as McGregor rises through the ranks of UFC – via multiple belts – to an iconic fight in Las Vegas, with dramatic fight scenes and exclusive behind the scenes access to his rise to the pinnacle of the sport.
Tumblr media
The new Sky Documentaries channel launches on May 27
I Am Ali
8pm, Tuesday June 9, Sky Sports Main Event, Sky Sports Action and NOW TV
Take in unparalleled access to Muhammad Ali’s story, based on an archive of his own audio journals and interviews with his inner circle as well as fellow boxers as we look back at a man known as ‘The Greatest’.
Klitschko
8pm, Tuesday June 16, Sky Sports Main Event, Sky Sports Action and NOW TV
From one boxing film to another as we move from the USA to Ukraine. Klitschko tells the story of boxing brothers Vitali and Wladimir Klitschko – detailing their rise from initial wins in the ring to worldwide boxing stardom.
’89
8pm, Tuesday June 23, Sky Sports Main Event, Sky Sports Premier League, Sky Sports Football, Sky Documentaries and NOW TV
This is the classic underdog story of the dying moments of the 88/89 season, when Arsenal – needing to win by two goals – took on title rivals Liverpool at their iconic home, Anfield. With appearances from North London legends including Tony Adams and Lee Dixon.
Take the Ball, Pass the Ball
Available now on Sky On Demand and NOW TV
A fascinating inside look at one of the most successful sides in club football history – Pep Guardiola’s Barcelona – and the philosophy that led them to incredible triumphs. Featuring memories and insight from the likes of Guardiola himself, Lionel Messi, Gerard Pique, Xavi and Andres Iniesta.
Life Of Ryan: Caretaker Manager
Available now on Sky On Demand and NOW TV
Follow Manchester United’s longest-serving player as he takes to the dugout for United’s 2013/14 Premier League season. This cinematic documentary celebrates Ryan Giggs as he leads the club he loves in the hope of Premier League glory. The documentary includes interviews from a range of footballing superstars including David Beckham, Diego Maradona and Eric Cantona.
require.config("shim":"facebook-sdk":"exports":"FB","baseUrl":"https://www.skysports.com/","paths":"skysports_com":"static/skysports_com-b3fbffb5f0195","skysports_digrev":"static/skysports_digrev-f17b87f0f7c8f","skysports_legacy":"static/skysports_legacy-e7dde831a4d39","skysports_ipad_components":"static/skysports_ipad_components-4798d45d25479","skysports_sap":"core/js/../static/js/skysports_sap","requireLib":"static/require-2.1.0-15f03d8ff7a4b","class":"static/class-55bbf080a62c3","countdown":"static/countdown-3c7569426f127","energize":"static/energize-bac53226fb-9795bcfacb255","hammer":"static/hammer-a592776ebb-f14662ea8bb34","marker-clusterer":"static/marker-clusterer-8a934d664ede6","moment":"static/moment-1.7.2-33075cfd4ad32","reqwest":"static/reqwest-a845dfd832-dea6ebed2de7d","scroll-pane":"static/ftscroller-280c6900bc-ca9da74da3fb9","underscore":"static/lodash.custom-80970c5a1825d","adaptive-content":"static/adaptive-content-1fc383fae518a","article-widget-betting":"static/article-widget-betting-7a9641160b027","app-bridge":"static/app-bridge-30b975666386a","article-advert":"static/article-advert-fa40febcc7b0f","article-outbrain":"static/article-outbrain-bba64c5034e96","autocomplete":"static/autocomplete-62886d6993248","autocomplete-lite":"static/autocomplete-lite-c397d58384aeb","accordian":"static/accordian-87ec71ccbfdd1","betting-lines":"static/betting-lines-31e5cdbecf2bc","bskyb-omniture":"static/bskyb-omniture-de3e9caef9fce","bskyb-omniture-1-2":"static/bskyb-omniture-1.2-ef8627d226d42","calendar-url-builder":"static/calendar-url-builder-863fca999d8c8","carousel":"static/carousel-cfdab6400e999","carousel-lite":"static/carousel-lite-520eccc372b67","close-me":"static/close-me-1dd5bf41462eb","content-stream":"static/content-stream-4ceef3bbd096b","content-swap":"static/content-swap-bdbe29a70d8f9","countdown-widget":"static/countdown-widget-459a93f477481","comments-reply":"static/comments-reply-81d5853bdd03b","cookie":"static/cookie-072824b3a5047","android-notice":"static/android-notice-58d95f174579a","create-audio":"static/create-audio-f77436036a203","create-video":"static/create-video-f5fe547b889be","create-video2":"static/create-video2-bb132ac918d30","dataset":"static/dataset-487d6875fe94d","datepicker":"static/datepicker-b112a28bd151b","datepicker2":"static/datepicker2-d10188465db39","dom":"static/dom-f554c2354ab77","dropdown":"static/dropdown-de4729ed67884","dropdown-select":"static/dropdown-select-bbaa962ff8888","edigital-survey":"static/edigital-survey-6.0.6.0-13762d4026255","element-listener":"static/element-listener-39391d1341a3c","environment":"static/environment-d24a016d1c736","events":"static/events-e6bde13ac56dc","facebook-sdk":"//connect.facebook.net/en_US/all","fastclick":"static/fastclick-ea596eafa5-1c2edee75a004","form":"static/form-269f9f014d35a","form-chart":"static/form-chart-8e3b2b92c7e77","form-validation":"static/form-validation-76d631ee9c0fb","html-poller":"static/html-poller-db12e18d06d04","implicit-personalisation-display":"static/implicit-personalisation-display-2bc93246729e4","implicit-personalisation-storage":"static/implicit-personalisation-storage-a4eb341b47077","implicit-personalisation-removal":"static/implicit-personalisation-removal-7556598e29ff5","inverted-listener":"static/inverted-listener-07a7ace73331d","iscroll-lite":"static/iscroll-lite-03ad473f62d1a","keyboard-listener":"static/keyboard-listener-f6b30a391df5b","keyboard-view":"static/keyboard-view-5a68be0e6dc00","lazy-images":"static/lazy-images-f5238f2864a52","live-article":"static/live-article-95ba706f060b3","live-cricket":"static/live-cricket-98d8debeb2633","live-sport":"static/live-sport-77265bd8792ec","live-update":"static/live-update-945d95543ad61","live-refresh":"static/live-refresh-5ebefb5206c82","live-refresh-darts-table-controller":"static/live-refresh-darts-table-controller-d6c7bb8af0efe","live-refresh-darts-table-view":"static/live-refresh-darts-table-view-5c4f5e87a3cb2","live-refresh-football-controller":"static/live-refresh-football-controller-461aca93a03fe","live-refresh-football-view":"static/live-refresh-football-view-e722175c6f5eb","live-refresh-fixture-update-controller":"static/live-refresh-fixture-update-controller-1234617fddd04","live-refresh-fixture-update-view":"static/live-refresh-fixture-update-view-aae190ead42d7","live-refresh-live-golf-leaderboard-controller":"static/live-refresh-live-golf-leaderboard-controller-c78264eefa25c","live-refresh-golf-matchplay-controller":"static/live-refresh-golf-matchplay-controller-141ff1ce16821","live-refresh-golf-matchplay-view":"static/live-refresh-golf-matchplay-view-562c7eea1e08b","live-refresh-match-header-controller":"static/live-refresh-match-header-controller-db2b9bbacac74","live-refresh-match-header-football-view":"static/live-refresh-match-header-football-view-f9ce5b3e5bde3","live-refresh-match-header-rugby-league-view":"static/live-refresh-match-header-rugby-league-view-34aa9cc8d67be","live-refresh-match-header-rugby-union-view":"static/live-refresh-match-header-rugby-union-view-a6b7dda93027f","live-refresh-match-stats-controller":"static/live-refresh-match-stats-controller-db8736f4b3e01","live-refresh-match-stats-view":"static/live-refresh-match-stats-view-62f02d64e4cd2","live-refresh-gp-standings-controller":"static/live-refresh-gp-standings-controller-aa40463310354","live-refresh-gp-standings-view":"static/live-refresh-gp-standings-view-b820cc96d1d26","live-refresh-tennis-controller":"static/live-refresh-tennis-controller-5681743439cec","live-refresh-tennis-view":"static/live-refresh-tennis-view-28ddbf0727027","live-refresh-news-list-controller":"static/live-refresh-news-list-controller-ee45762f7dbe7","live-refresh-news-list-view":"static/live-refresh-news-list-view-9c47d574e49d4","live-refresh-livefyre-pinned-controller":"static/live-refresh-livefyre-pinned-controller-44287b34c8506","live-refresh-livefyre-pinned-view":"static/live-refresh-livefyre-pinned-view-a78229a5d01c4","live-refresh-live-table-controller":"static/live-refresh-live-table-controller-053e53c72d2a5","live-refresh-live-table-view":"static/live-refresh-live-table-view-acc034f23d117","live-refresh-live-table-static-view":"static/live-refresh-live-table-static-view-bbff46626848e","live-refresh-masters-live-panel-controller":"static/live-refresh-masters-live-panel-controller-b237958f07549","live-refresh-matchplay-table-controller":"static/live-refresh-matchplay-table-controller-c8d653e8ec9e1","live-refresh-matchplay-table-view":"static/live-refresh-matchplay-table-view-aafd4fb26b14f","live-refresh-ryder-cup-controller":"static/live-refresh-ryder-cup-controller-737295aac3b2e","live-refresh-ryder-cup-view":"static/live-refresh-ryder-cup-view-8975b104d8f84","live-refresh-status-lookup":"static/live-refresh-status-lookup-58cee7af21a4a","live-refresh-switch":"static/live-refresh-switch-122a55d025f32","live-refresh-team-events-controller":"static/live-refresh-team-events-controller-4cb3d870d779b","live-refresh-team-events-view":"static/live-refresh-team-events-view-705c641b015af","live-text":"static/live-text-bbd7665a86991","live-refresh-swingometer-controller":"static/live-refresh-swingometer-controller-b7ade1b72e79a","live-refresh-swingometer-view":"static/live-refresh-swingometer-view-425bcd02cb919","livefyre-auth":"static/livefyre-auth-d30ce39d9f031","livefyre-social":"static/livefyre-social-2ef6165825d8a","load-into":"static/load-into-6af455f20f3bd","load-more":"static/load-more-765d8e57df5c0","load-more2":"static/load-more-05a9bb0171a4e","match-head-switch":"static/match-head-switch-b85e40ff913e7","load-more-inline":"static/load-more-inline-6ee576a87aef2","load-more-once":"static/load-more-once-b9144ab829181","map":"static/map-94fcb75a28607","media-query":"static/media-query-0296e4082a758","now-tv":"static/now-tv-8700a2f7d2f1e","most-popular":"static/most-popular-c1147764fe234","observable":"static/observable-6a091c15b9a4a","open-top":"static/open-top-3eff6bd9d5565","overlay":"static/overlay-b444bdc049b12","overlay-widget":"static/overlay-widget-56d2dc14d6d21","page-nav":"static/page-nav-479fc6b85357e","parse-date":"static/parse-date-6463ce015eee7","page-filters":"static/page-filters-5f38de0bf6eeb","persistent-autocomplete":"static/persistent-autocomplete-8459865f00a4f","polaris-glint":"static/polaris-glint-90f846e5378ec","pikaday":"static/pikaday-10e563e7df76b","pl-clip-promo":"static/pl-clip-promo-1bbc9f6f7fcec","poller":"static/poller-b0ddbff69a6a9","polls":"static/polls-2ef656ad8404e","poll-ig":"static/poll-ig-e17180cbcc564","media-playlist":"static/media-playlist-ebc8d2abe3e18","postpone-load":"static/postpone-load-2ae208049e0f1","postpone-load2":"static/postpone-load2-6ad484e51343f","postscribe":"static/postscribe-3737e3c2f9-f3bc808a8b738","pub-sub":"static/pub-sub-9323318c11e08","roadblock":"static/roadblock-161d7533097ac","update-content":"static/update-content-b6fc0cfd94862","script":"static/script-27238830c957e","scroll-to":"static/scroll-to-97ec63ad7135c","scribble-article":"core/js/modules/scribble-article","section-nav":"static/section-nav-3aff450804b4f","selectable":"static/selectable-f199bca8d8e16","selectable-list-view":"static/selectable-list-view-3330035b870a5","share-button":"static/share-button-606792a8e7289","site-layout-primary":"static/site-layout-primary-d66ac28011c25","site-nav-desktop":"static/site-nav-desktop-9b1b26877d782","sky-go":"static/sky-go-a6fba47493d8e","skyid-login":"static/skyid-login-9f5140a550d32","is-loggedin":"static/is-loggedin-69dfe40b9565f","sky-sports-date":"static/sky-sports-date-e985472a648e9","squad-selector":"static/squad-selector-45e17c533f3a2","social-map":"static/social-map-8bc134219358b","sp-player":"static/sp-player-5ef6b052166d3","sticky-scroll":"static/sticky-scroll-4ccc7640bda1f","string":"static/string-19008c0fbd461","swipe-nav":"static/swipe-nav-18987ddd0e3ed","subscriber-video":"static/subscriber-video-5d8435b0ea5ab","table-sorter":"static/table-sorter-7d5988301396e","table-sorter-lite":"static/table-sorter-3d24f6a403740","tabs":"static/tabs-b20fcf8e1c825","tabs-lite":"static/tabs-lite-cb10daad481bf","tabs-filter":"static/tabs-filter-1ef8b2a921435","tab-navigation":"static/tab-navigation-68b7c289a7569","team-formations":"static/team-formations-a90922defa046","thumbs":"static/thumbs-0cf143fb65daa","toggle-class":"static/toggle-class-dd3a8c4ce2c14","toggle-switch":"static/toggle-switch-4b14c9522febe","trending":"static/trending-e0bb96dbc6ece","trigger-event":"static/trigger-event-580cd06dcede1","tv-guide":"static/tv-guide-495271c3f333e","update-html":"static/update-html-7913f53b11d6f","update-text":"static/update-text-82964c420cfb8","user":"core/js/modules/user","util":"static/util-b69470ac564b1","validator":"static/validator-f3b00bc96d618","vidiprinter":"static/vidiprinter-e8c9174ecfa73","vm-suppression":"static/vm-suppression-9a7148a4170ba","web-notifications":"static/web-notifications-a91a27e944caf","widget":"static/widget-e29945f3a184a","widget-lite":"static/widget-lite-a450505656ea9","widget-loader":"static/widget-loader-a0232be50e094","window-observer":"static/window-observer-b10f792cfb582","your-say":"static/your-say-3b2bbc5fcf119");
require(['skysports_digrev', 'sdc-site-pub-sub'], function (appController, pubsub) );
0 notes
siva3155 · 5 years ago
Text
300+ TOP FILEMAKER Interview Questions and Answers
FILEMAKER Interview Questions for freshers experienced :-
1.What is FileMaker Pro? FileMaker Pro is a 32 bit, Y2K compliant, cross-platform, fully relational, database program. Similar to Microsoft Access, the current version of FileMaker is a fully relational database development tool that allows one-to-one, one-to-many, many-to-one, and many-to-many relations between files (tables). Another one of FileMaker Pro's advantage is the FileMaker Developer tools that allows us to 'bundle' the form files with the FileMaker Runtime engine that allows our outside customers to use WSDOT forms without requiring them to purchase any additional software. 2.What are the symptoms of a corrupt FileMaker file? Symptoms vary from corruption type and level of corruption. Maybe your FileMaker application freezes when the file is tried to open, or maybe an error message is shown when you click the file to open it. 3.Is it possible to search any FileMaker .fp7 file? FileMaker Recovery Software has an inbuilt option to search FP7 files in a specified location. File properties like modification date, creation date, size, etc. are shown in the search result for accurate selection. 4.How is FileMaker Recovery Software different from other similar products in market? Many features have been included in latest version of FileMaker Recovery Software. Latest version of FileMaker Recovery Software supports File Maker Pro 10/11/Pro/Advance and above. Search option in the preview, selective recovery of a specific table, log summary, etc. make it above other similar software applications in the market. 5.What is FileMaker Recovery Software? FileMaker Recovery Software is used to repair, restore and recover corrupt FileMaker database (.fp7) files. A search feature is provided that helps in searching all the .fp7 files present in a drive or folder. A new FileMaker file is set as target to store the recovered table data. Data of Text, Number, Date, Timestamp, Calculation, Container and Summary data type are recovered back in the repaired database file. 6.Can I repair a FileMaker database for trial and evaluation without payment? Yes, you can download FileMaker Recovery Software absolutely free of cost. Preview is shown in the demo version for customer evaluation. If you are satisfied by the scanned results, you can register the demo version to save the recovered FileMaker database. 7.What is new in FileMaker Pro 6? The best just got better with FileMaker Pro 6 database software. It features digital image capture and import; more than 20 modern and powerful templates for "instant productivity" in business, education and home; many time-saving features like Format Painter and Custom Dialog Boxes for users and developers; and integrated XML support so FileMaker can exchange data with a large and growing number of other applications. FileMaker Pro 6 will jump-start the productivity and creativity of workgroups ranging from entire small businesses to departments within the enterprise. 8.Why is the new FileMaker Pro 6 available before other revised products? FileMaker Pro 6 files share the same file format as FileMaker Pro 5 and 5.5 files. Thus, all three versions may co-exist on the same network. In addition, all versions utilize the current FileMaker Server (now relabeled without a version number) features, enabling large workgroups to share information seamlessly. 9.Is XML import/export support in FileMaker Pro 6 a big deal? Absolutely the widespread support of XML (Extensible Markup Language) standards means FileMaker Pro 6 can exchange data with a large and growing number of other applications without complex and costly converting of data between proprietary formats. A developer can easily empower a workgroup using FileMaker Pro 6 to, for example, find and get data from Websites, import accounting data from QuickBooks, or query corporate databases without using ODBC drivers. With XML export, FileMaker Pro 6 users can share information with users of other applications. For example, users can export formatted FileMaker data in an attachment to an email, into Microsoft Excel, or into document-authoring applications. 10.What's new about XML support in FileMaker Pro 6? In the past, accessing FileMaker data as XML required users to make requests to the FileMaker Web Companion from an external application; in other words, it was "pull" only through the Web Companion. Additionally, processing XSLT style sheets required the user to have installed an XSLT processor on the client machine. With FileMaker Pro 6 the XML capabilities are integrated into the product as import/export menu selections without the need for the Web Companion. Alternatively, the customer can script XML data import and export. Also within FileMaker Pro 6 is an XSLT processor allowing style sheets can be processed without the need for the customer to install their own.
Tumblr media
FILEMAKER Interview Questions 11.How hard is it to use XML import/export? Can anyone use it? While the creation of the XSLT style sheets does require a good understanding of XML and XSLT, the benefits of our XML import/export can be enjoyed by all users. Note that a developer can empower an entire workgroup, very efficiently, to enjoy the benefits of XML data-exchange while hiding the plumbing from the users. To further assist our customers with better understanding of XML and XSLT, we ship 8 XSLT style sheet examples with FileMaker Pro 6. Furthermore, customers can visit the FileMaker XSLT Library, which is part of our FileMaker XML Central. The FileMaker XSLT Library is a repository of XML/XSLT examples that are available for download at no charge. 12.Why did FileMaker add integrated XML support in FileMaker Pro 6? XML support is the tool that best accomplishes this task. With the implementation of our XML support, FileMaker Pro 6 users are now able to gather data from more data-sources and share data with more applications.FileMaker Pro 6 customers can benefit from XML import and export. Through the creation of an XSLT style sheet , a workgroup can: Import XML data from a SQL server without the use of ODBC drivers. Share information with other workgroups who don’t even use FileMaker Pro by sending data from FileMaker directly into a formatted Excel file (*.xls) or other text-based file formats. Create charts and graphics (*.svg) to represent FileMaker data. 13. Is there RAIC support for Instant Web Publishing in FileMaker Pro 6? There is no support for RAIC technology in FileMaker Pro 6. Use FileMaker Pro 6 Unlimited to deploy Web-based solutions to an unlimited number of users. It also includes the FileMaker Pro Web Server Connector and support for RAIC, which can increase the performance and scalability of your FileMaker Pro web databases. Toolbars are not supported under Mac OS X. 14.What is FileMaker Pro 5.5 Unlimited? FileMaker Pro 5.5 Unlimited includes all of the powerful desktop database functionality of FileMaker Pro 5.5, plus it allows databases to be hosted via the Web to an unlimited number of unique visitors with unique IP addresses. FileMaker Pro 5.5 Unlimited also includes the Web Server Connector and tools needed to use and access advanced functionalities such as Custom Web Publishing (via CDML), XML, JDBC, Java class libraries, and JavaScript. 15.What is the difference between FileMaker Pro 5.5 and FileMaker Pro 5.5 Unlimited? There are four major differences between FileMaker Pro 5.5 and FileMaker Pro 5.5 Unlimited: The Web Companion that ships with FileMaker Pro 5.5 Unlimited allows access to the Web Companion for an unlimited number of web browsers. The Web Companion that ships with FileMaker Pro 5.5 is limited to 10 IP addresses in a rolling 12 hour period. FileMaker Pro 5.5 Unlimited includes the FileMaker Web Server Connector. Additional copies of FileMaker Pro 5.5 Unlimited can be used to set up a Redundant Array of Inexpensive Computers (RAIC) structure to take advantage of scalable load balancing, and fault tolerance, to increase the performance of FileMaker web enabled databases. Computers running Mac OS X cannot serve as RAIC machines FileMaker Pro 5.5 Unlimited can be used with various CGIs, middleware, and application servers for deployment across the Web. Tools and information needed to implement solutions using advanced functionalities (JDBC driver, Java class library, Custom Web Publishing , Custom Workgroup Portal, XML) are not included in FileMaker Pro 5.5. 16.What is the FileMaker Web Server Connector? The FileMaker Web Server Connector is a Java servlet that is used to connect FileMaker Pro 5.5 Unlimited with powerful web servers. A servlet is a standard Java based mechanism for extending the functionality of a web server. The FileMaker Web Server Connector is used to pass through (or relay) requests received on a web server to FileMaker. The reasons to use the FileMaker Web Server Connector include. To take advantage of other web server plug-ins and features including SSL and server-side includes, provide a Redundant Array of Inexpensive Computers (RAIC) structure to increase throughput and reliability, increase performance by storing static pages and graphic images on the Web server, bypassing the Web Companion for pages that don't involve databases, and provide redundancy to allow for operation through failure situations. 17.Can I use the FileMaker Web Server Connector with FileMaker Pro 5.5? The FileMaker Web Server Connector is designed to work only with FileMaker Pro 5.5 Unlimited, the dedicated web publishing product in our product family. 18.Can I use the FileMaker Pro 5.5 Unlimited Web Server Connector with Instant Web Publishing? No. The improved FileMaker Pro 5.5 Unlimited Web Server Connector is intended for use with Custom Web Publishing. 19.How can I run reports and print labels via browser in databases hosted under FileMaker Pro Unlimited? If you need more functionality than browsing, searching, adding, updating, or deleting records, you will want to access the database using a copy of FileMaker Pro, rather than a browser. 20.How can I set up a Redundant Array of Inexpensive Computers (RAIC) with FileMaker Pro 5.5 Unlimited to increase scalability, performance and robustness? The FileMaker Web Server Connector, included with FileMaker Pro 5.5 Unlimited, lets you set up a RAIC. A RAIC increases the scalability of your web-based FileMaker Pro solutions and helps ensure operation through fail-over situations. To set up a RAIC, an additional copy of FileMaker Pro 5.5 Unlimited is required for each CPU you wish to add to the RAIC. 21.What languages will FileMaker Pro 5.5 Unlimited be available in? FileMaker Pro 5.5 Unlimited in Worldwide English, French, Italian, German, Swedish, Dutch, Japanese and Spanish. 22.What are the price and availability of FileMaker Pro 5.5 Unlimited? FileMaker Pro 5.5 Unlimited is currently available. Estimated retail price in the U.S. is $999. Upgrade price for licensed owners of FileMaker Pro 5 Unlimited is US $499. Volume license pricing is available. 23.Do I have to use the FileMaker Web Server Connector when I install FileMaker Pro 5.5 Unlimited? No. If you want to use FileMaker and simply have more than 10 IP addresses accessing your copy of FileMaker in a rolling 12 hour period and do not need to add scalability and load balancing to your FileMaker web solutions, you can simply install the "unlocked" version of FileMaker Pro 5.5 that ships with FileMaker Pro 5.5 Unlimited. 24.Is FileMaker Pro 5.5 Unlimited certified for Windows 2000? FileMaker Pro 5.5 Unlimited is certified for Windows 2000 Professional. 25.Why did we build FM Starting Point? When we worked with FileMaker, Inc. to rebuild and clean up the “Starter Solution Templates,” a premium was placed on simple functionality that would be easy for brand new FileMaker users to take apart and customize. Of course, with simplicity elevated to such a high degree, overall usefulness of a database can be quite limited. There is, therefore, a genuine need for a more robust FREE starter solution for FileMaker users; this tool meets those needs. 26.What is new in FM Starting Point 2? With the release of FileMaker 11, we decided to update our FM Starting Point template with a few new features. A few of these include Charting throughout the system, inventory tracking between the Invoice and Products module, and hourly rates in the Timesheets module. You will find a brand new Summary tab in the Projects Module that collects information from the Inventory, Expenses, and Timesheets tables to produce graphs showing the current status and profitability of a project. All this and more you will find in the new version. Once again, FM Starting Point 2 is a FREE solution so you can go ahead and download it as soon as you get FileMaker 11. 27.Will FM Starting Point 1 still be available? A new link has be put onto the FM Starting Point website for downloading our last release, FM Starting Point 1.0v15. 28.Is FileMaker Inc. responsible for this Database? No. FM Starting Point was influenced by the redevelopment of FileMaker’s “Starter Solution Templates” which are already included for FREE with each install of FileMaker Pro. FileMaker Inc. has not underwritten this enhanced solution. FMI staff provided feedback for the included features, and we greatly appreciate their assistance. All quality assurance testing was performed by RCC and not FMI. 29.How is this different than Data4Life? Some FileMaker users are aware of another FREE database offered, called Data4Life. Data4Life is designed for personal use, and not business use. FM Starting Point targeted towards small businesses, work groups, and non-profit organizations. 30.Does FM Starting Point connect to QuickBooks? FM Starting Point can connect to QuickBooks (on Windows only) via the use of third party plug-ins. The Mac version of QuickBooks has some limitations that prevent it from communicating with a Plug-in unless you are a FileMaker “power user” then you might need to get some help from a FileMaker developer with this task. 31.Does FM Starting Point connect to iCal or Address book on a Mac? FM Starting Point can connect to these other applications via the use of third party plug-ins. Unless you are a FileMaker “power user” then you might need to get some help from a FileMaker developer with this task. 32.Is there an instruction manual for FM Starting Point? No. There are several instructional on screen help videos to help get users rolling in the new system. We are also commenting on the scripts and various features within the database template. FM Starting Point is design for new users so it is not too complex. Few people read the manuals anyway. They just hack their way through a product. However, if someone wants to write a manual, and then give it away to everyone, let us know and we’ll post it for you. 33.What are the different kinds of Email I can send from FM Starting Point? Primarily, the email capabilities are within the "contacts" modules, where you can shoot off a myriad of different "canned" emails. These will be plain text emails, since that is what the new built in FileMaker 10 feature supports. Email may be sent through a users email client OR use the new “Direct Send” capability of FileMaker Pro 10. 34.When I am reviewing a specific to-do, from the to-do list, and I select a due date, the Window will flash. Why is this? We had to use a script trigger. When the due date is modified, it selects the to-do list window, and causes a refresh to occur. We did this because FileMaker 10’s new sticky sort capability would frequently re-sort the new to-do item off the visible list (above or below), and would confuse the user when the to-do pop up is closed. 35.In the FileMaker 10 Starter Solutions, there is frequent use of "Type Ahead" aka Clairvoyance. Why is this missing from FM Starting Point? Normally, we added functionality to the system, but not in this case. Type ahead causes a performance drain that is very noticeable for medium sized data sets, when accessed over a Wide Area network or Internet connection. We expect a fair number of people to access FMSP, hosted at their offices, or at a Hosting company, and then accessing the database remotely. These people would be highly disappointed by the huge slow down of FileMaker when using “Type Ahead” features. So to prevent nasty phone calls and flaming emails, we dropped this capability out of FMSP. If you run FMSP as a single user, on your local computer, feel free to turn “Type Ahead” back on. 36.What is FREE SuperContainer Hosted Lite? SuperContainer Hosted Lite is a FREE limited version of SuperContainer that is hosted by 360Works and is built specifically into FM Starting Point. The Lite Hosting Plan includes the following: No limit on number of users within your organization. Maximum of 2 megabytes per file. Limit of 10,000 total items. 250 megabytes total storage. Up to 1 gigabyte of download/upload traffic per month. Thumbnails display at a maximum resolution of 300x300. For use exclusively with the FM Starting Point solution. 37.What is SuperContainer Hosted Pro? SuperContainer Hosted Pro is a more powerful version of SuperContainer that is hosted by 360Works and is built specifically into FM Starting Point. The “Hosted Pro” version includes the following: No limit on number of users within your organization. Unlimited file size, total items, and thumbnail resolution. 20 gigabytes total storage. Up to 20 gigabytes of download/upload traffic per month. For use with any solution, not just Starting Point. Monthly charge of $49 US. 38.What is SuperContainer Enterprise? SuperContainer Enterprise is for an unlimited number of users and access via the web, running on your own in-house FileMaker Server. The Enterprise version includes the following: No limit on number of users within your organization. Accessible only with a Web Viewer in FileMaker Pro, or via a web browser for viewing and uploading files from the web. Unlimited file size, total items, thumbnail resolution (limited only by space on your server). Unlimited total storage (limited only by space on your server). Unlimited download/upload traffic per month (limited only by bandwidth to your server). Supports SSL encryption. For use with any solution, not just Starting Point. One-time charge of $695 US. 39.What is SuperContainer Workgroup? SuperContainer Workgroup is for up to 10 FileMaker users, running on your own in-house FileMaker Server. The Workgroup version includes the following: Up to 10 users within your organization. Accessible only with a Web Viewer in FileMaker Pro (not via the a web browser). Unlimited file size, total items, thumbnail resolution (limited only by space on your server). Unlimited total storage (limited only by space on your server). Unlimited download/upload traffic per month (limited only by bandwidth to your server). Supports SSL encryption. For use with any solution, not just Starting Point. One-time charge of $195 US. 40.Does FileMaker Work on the iPhone and iPad? Yes! The product is called “FileMaker Go,” and can be installed on either the iPhone or iPad, after being purchased from the App Store. You need this software before you can use FM Starting Point on these devices. Once you have FM Go installed, you have the choice of accessing the database as shared from a FileMaker Server, or as shared from a single desktop with peer to peer sharing turned on. Also, for maximum speed, you can email or otherwise transfer FMSP to your iPhone or iPad and have it run on the device locally. 41.How do I download the iPhone or iPad version of FMSP? The iPhone and iPad version of FMSP are all “rolled together” into a single FileMaker file – the same file that is accessed by the desktop copy of FileMaker Pro. All three versions are in a single file. This way, users with different devices can log onto the same database and share data. 42.Did you make some screens designed just for the iPhone or iPad? We did actually develop some screens specific to these devices. Building an interface for a touchscreen device is somewhat different than for a desktop computer with a mouse. For the iPhone, we built out screens that allow user to find, view, edit and add contacts to FMSP. Plus, if you click the contact's phone number, it will actually dial the number and make the call on the iPhone. For the iPad, we took all the screens and functionality of FMSP and duplicated them. Then we weaked these duplicated screens so they have bigger buttons and fields things you need for a touchscreen device. 43.Does FMSP and FileMaker Go on the iPhone work with the camera built into my iPhone? Unfortunately, no: integration with the iPhone's camera is not supported in this initial release of FileMaker Go. 44.Where did the charts go in FMSP on my iPhone and iPad? Why can't I save as PDF or Print? Charting is not yet a supported feature of FileMaker Go. Same for making PDFs and printing. 45.Can Recovery for FileMaker repair my FileMaker Pro database? The effective way to find out if a FileMaker Pro database is recoverable is to try the demo version of Recovery for FileMaker on it. 46.What limitations does the demo version of Recovery for FileMaker have? Demo version recovers limited number of the database rows. The remaining rows will be blank. Full version will restore demo-limited rows as well. 47.I have tried the demo. How do I decide whether to purchase the full version of Recovery for FileMaker? Evaluating the results of demo recovery can help in making the decision. 48. Why is WSDOT using FileMaker Pro for electronic forms? In October 1992, the department started researching and testing different software packages to develop and deploy electronic forms department wide. None of the software provided all of the features initially defined. FileMaker Pro (version 2.0) was chosen, providing the most features, flexibility, and usability within the WSDOT IT infrastructure. 49.After successful recovery of the original database a new .DBF file is created. What is the procedure for transferring data from this temporary file to a database? You should simply import data from the resulting file in .DBF format into a new database. 50.Will FMTouch support the Apple iPad? Yes, we have already tested and written the new code for FMTouch and the Apple iPad. 51.Will FMTouch work with FileMaker 11? Yes, FMTouch works with FileMaker 11. There was an update to a new plug-in for FMTouch FileMaker 11 support. If you are using FileMaker 11, please make sure you download the new plug-in. 52.Will FMTouch work on both the iPhone and the iPod iTouch? Yes, FMTouch works with both the iPhone and the iPod iTouch. 53.Do I have to be connected to the internet? No, you do not have to be connected to the internet. FMTouch runs locally on your mobile device as a local application. You can sync FMTouch while you have FileMaker running with the sync plug-in - sync once an hour, once a day on your own schedule. 54.Will Runtime solutions run on FMTouch? Yes, runtime solutions work on FMTouch. 55.What versions of FileMaker are supported? FMTouch works with FileMaker version 8-11 and beyond. We will not be releasing versions for FileMaker 7 and below. 56.Do I have to design special layouts or databases? You should make database layouts that would render effectively on the iPhone. Many developers are simply adding iPhone specific layouts. Smaller databases are also faster and take less time to load. 57.Is FMTouch Relational? Yes, and you will find that the ability to use and edit portals is great bonus. You have the ability to have many related tables and many related databases all talking to one another. 58.Can I have multiple layouts? Yes, you can have multiple layouts, and you can easily deselect the layouts that you don't want to display. 59.Can I do scripting and calculations? Scripting and Calculations are supported. 60.Are repeating fields supported? Yes, repeating fields are now supported as are merge fields. As of version 1.23. Note: Repeating fields require FileMaker 9+. 61.Will FMTouch work for both Windows and Macintosh? Yes, FMTouch works equally well with both Macintosh and Windows OS. 62.What versions of FileMaker does FMTouch support? Initially you will need FileMaker Advanced to create your DDR. Once this is generated, FMTouch can be used with FileMaker Pro 8-11. Note: 8.5 is needed for webviewer support. 63.Why do I need FileMaker Advanced? FileMaker Advanced enables you to generate your database DDR. This information is needed to help FMTouch create your database. Once the DDR is created you can use regular FileMaker Pro 8-10. 64.Will enterprise or developer licenses be available? Yes, enterprise licensing is available. 65.I am having problems syncing with my Mac? If you are having problems syncing 99% of the time it is because of a few things. You have a firewall set up - and the correct port is not open. You are trying to sync through the USB cable. You do not have the plug-in correctly installed. 66.I am having problems syncing with my PC? If you are having problems syncing 99% of the time it is because of a few things. You have a firewall set up - and the correct port is not open. You are trying to sync through the USB cable. You do not have the plug-in correctly installed. 67.Do you have an online Forum? Yes 68.Are container fields supported? Yes, beginning with version 1.30 we added container field support. 69.Can I sync to FileMaker Server on Windows and MaC? Yes, check out the user’s guide server section you can sync to both Mac and PC Server with FileMaker Server 9, 10 and 11. 70.What version of FileMaker Pro is the department using? The department is currently using FileMaker Pro 11.0v3. FileMaker Pro is a Level Playing Field software and is installed on all WSDOT workstations. For our downloadable eForms, we are using version 11.0v3 of the FileMaker Pro runtime engine. FileMaker Questions and Answers Pdf Download Read the full article
0 notes
tak4hir0 · 5 years ago
Link
1. Don’t use public accessor within classesDon’t: Do: Why? All members within class are public by default (and always public in runtime, TS private/protected will "hide" particular class properties/methods only during compile time). Don't introduce extra churn to your codebase. Also using publicaccessor is not "valid/idiomatic javascript" 2. Don’t use private accessor within Component classDon’t: Good: Better: Why: private accessor won't make your properties/methods on class private during runtime. It's just TypeScript "emulation during compile time". Don't get fooled and make things "private" by using well known patterns like: In reality, you should almost never need to work directly with React Component instance nor accessing its class properties. 3. Don’t use protected accessor within Component classDon’t: Do: Why: Using protected is an immediate "RED ALERT" 🚨🚨🚨 in terms of functional patterns leverage with React. There are more effective patterns like this for extending behaviour of some component. You can use: just extract the logic to separate component and use it as seen aboveHoC (high order function) and functional composition.CaaF ( children as a function )4. Don’t use enumDon’t: Good: If you need to support runtime enums use following pattern: Better: If you don’t need to support runtime enums, all you need to use are type literals: Why?: To use enum within TypeScript might be very tempting, especially if you're coming from language like C# or Java. But there are better ways how to interpret both with well known JS idiomatic patterns or as can be seen in "Better" example just by using compile time type literals. Enums compiled output generates unnecessary boilerplate (which can be mitigated with const enum though. Also string enums are better in this one)Non string Enums don’t narrow to proper number type literal, which can introduce unhandled bug within your appIt’s not standard/idiomatic JavaScript (although enum is reserved word in ECMA standard)Cannot be used with babel for transpiling 👀🙇‍Enum helperIn our “Good” example, you might think like, ugh that’s a lot of boilerplate dude! I hear you my friends. Loud and clear 🙏 If you need to support runtime enums for various reasons, you can leverage small utility function from rex-tils library like showcased here: 5. Don’t use constructor for class ComponentsDon’t: Do: Why: There is really no need to use constructor within React Component. If you do so, you need to provide more code boilerplate and also need to call super with provided props ( if you forget to pass props to your super, your component will contain bugs as props will not be propagated correctly). But… but… hey ! React official docs use constructor! 👉 That’s fine (React team uses current version of JS to showcase stuff) But… but…, class properties are not standard JavaScript! 👉 Class fields are in Stage 3, which means they are gonna be implemented in JS soon Initializing state with some logicOf course you may ask, what if I need to introduce some logic to initialize component state, or even to initialize the state from some dependant values, like props for example. Answer to your question is rather straightforward. Just define a pure function outside the component with your custom logic (as a “side effect” you’ll get easily tested code as well 👌). 6. Don’t use decorators for class ComponentsDon’t: Good: Better: Why: Decorators are parasitic 🐛 👀 🤢 You won’t be able to get original/clean version of your class.TypeScript uses old version of decorator proposal which isn’t gonna be implemented in ECMAscript standard 🚨.It adds additional runtime code and processing time execution to your app.What is most important though, in terms of type checking within JSX, is, that decorators don’t extend class type definition. That means (in our example), that our Container component, will have absolutely no type information for consumer about added/removed props.7. Use lookup types for accessing component State/Props types🙇‍ lookup types Don’t: Do: Why: Exporting Props or State from your component implementation is making your API surface bigger.You should always ask a question, why consumers of your component should be able to import explicit State/Props type? If they really need that, they can always access it via type lookup functionality. So cleaner API but type information is still there for everyone. Win Win 💪If you need to provide a complex Props type though, it should be extracted to models/types file exported as Public API.8. Always provide explicit type for children PropsDon’t: Do: Why: children prop is annotated as optional within both Component and Functional Component in react.d.ts which just mirrors the implementation how React handles children. While that's ok and everything, I prefer to be explicit with component API.if you plan to use children for content projection, make sure to explicit annotate it with type of your choosing and in opposite, if your component doesn't use it, prevent it's usage with never type.Children type constraint 🚸Hey, mister Skateboarder ! I have a question ✋: What types can be used for children annotation in TypeScript ? I mean, can I constraint children to be only a particular type of Component (like is possible with Flow) ? Something like Tab within Tabs children: Tab[] ? Unfortunately not 🙃, as TypeScript isn’t able to “parse” output of JSX.factory 👉 React.createElement which returns JSX.Element from global namespace, which so what compiler gets is an object type, with type checking turned off (WARNING:every time you any a kitten dies 🙀😅) Or as stated in TypeScript docs 👀: “By default the result of a JSX expression is typed as any. You can customize the type by specifying the JSX.Element interface. However, it is not possible to retrieve type information about the element, attributes or children of the JSX from this interface. It is a black box ⬛️ 📦." NOTE: TS 2.8 introduced locally scoped JSX namespaces, which may help to resolve this feature in the future. Watch this space! We can use following types for annotating children: ReactNode | ReactChild | ReactElementobject | {[key:string]:unknown} | MyModelprimitives string | number | boolean where T can be any of formernever | null | undefined ( null and undefined doesn't make much sense though )9. Use type inference for defining Component State or DefaultPropsDon’t: Good: Better: By making freezing initialState/defaultProps, type system will infer correct readonly types (when someone would accidentally set some value, he would get compile error). Also marking both static defaultProps and state as readonly within the class, is a nice touch, to prevent us from making any runtime errors when incorrectly setting state via this.state = {...} Why: Type information is always synced with implementation as source of truth is only one thing 👉 THE IMPLEMENTATION! 💙Less type boilerplateMore readable codeby adding readonly modifier and freezing the object, any mutation within your component will immediately end with compile error, which will prevent any runtime error = happy consumers of your app!What if I wanna use more complicated type within state or default props?Use as operator to cast your properties within the constant. Example: How to infer state type if I wanna use derived state from props?Easy 😎… We will use pattern introduced in tip no. 5 with power of conditional types (in particular, standard lib.d.ts ReturnTypemapped type, which infers return type of any function ✌️)
0 notes
from-my-hammock-blog · 8 years ago
Text
Date #6
48 HOURS LEFT
As the first one out the door with props in hand, I’m leading the 48 hour film festival and it's only just started.  Another moment later and I find that my motorcycle is going to take me about as far as i'm willing to push it.  Fine, starting in last place means I only have room to move forward.
Situations like these are why they invented friends.  Waiting for Gabe to come rescue me I sit outside the Lyric Cinema Cafe and use the unexpected downtime to brainstorm ideas for our up incoming production.  
How do I write a script based on a ninja mask, a plastic army helmet, and one pair of margarita glasses featuring a prosthetic mustache?
With a bit of creative spirit and moxy, that's how.
Absorbed in the columns of my spiral I almost didn’t notice my knight in shining armor arriving to save me from my stationary fate.  Reluctantly, I left the bike behind so we could hurry to our set location; after all, I’d already wasted half an hour and I only had 95 of those left until I had to be back here with a fully packaged movie.  
Stopping only to pick up cameras and people named Robert we raced towards berthoud, hiding amongst its back roads and dirt driveways was the rest of our team.  The sun had set and the oh so familiar darkness threatened to swallow my headlights as I challenged the road to hold me to this earth.  I had lost time which I desperately needed and i intended to make it up.
The sharp crackling of dirt under my tires signaled my arrival and we barreled through the doors that I didn't recognize and into the smells I could never forget.  Our team sat around the kitchen and after raiding the pizza boxes our hosts had left for us we got to work.  
Dust and grime are no match for these guys, within hours a barn used for storing lumber and beer growlers had become the site of a college kids dream party venue.  Strung by ribbon, balloons reached to scratch the heads of those tall enough to enjoy their static touch.  Flags and lights hung from every imaginable location and the missing strays from costumes littered the floor and all while the greatest rager scene was being constructed I sat hammering out the basics for our script.  
40 HOURS LEFT.
Time is of the essence.  So there's no need to waste it when you still have the opportunity for some sleep.  We break for the night and retreat back home to our beds knowing that we may not get another chance for some time.
36 HOURS LEFT
Up bright and early and running on a refreshing 4 hours of sleep, Nick and I arrive to set up final preparations before we can start filming our first scene. Expensive lights, expensive mics, expensive cameras and lenses, this hobby shows little mercy for the clumsy.  
Finally, a few hours later and I get to stand in front of a set filled with an equipment set up I've only dreamed about and a crew that no one could ever have dreamed up.  Armed with our sharp wit and an ever encroaching case a sleep deprivation we labor endlessly until our actors can barely get the energy to speak their lines, the barn gets colder and colder with every passing hour and soon we’re shaking from the freezing conditions. Our space heater is too loud and we have to turn it off or it fills our equipment with brown noise.  
18 HOURS LEFT
Nerves fried, actors cold, bottles broken, and spirits high; we push so late into the night that the next morning's light begins to burn the eastern horizons.  If it wasn’t for the unbelievable stamina of the entire crew and the ridiculous humor there was no way this project would have gotten done and at 3:00 Sunday  morning I could officially call our last shot a wrap.  We did it, we were done.
10 HOURS LEFT
I say done while I’m writing this blog next to the laptop containing the unfinished edit. (It’s a work in progress.)  Caleb and I finished clean up and left location at 5:00 ready to tackle the final leg of our journey, the edit.  
4 HOURS LEFT
Sitting at the end of one of the more ambitious and fulfilling goals I’ve ever set out to accomplish I can’t help but be thankful for everyone that helped make this possible.  Working with such talented friends on this film has been one of my favorite life experiences and now that ive been up for over 36 hours with no sleep all I can say is “When’s the next project?”
10 MINUTES LEFT
Get your fucking ass moving! I sprint down the street, computer in hand while the program is trying to finish exporting our film.  Holy shit this is way too close!
We made it, with 1 minute to spare.
“Imagine there's a wall, and once you push through it anything becomes possible.  You can go for weeks without sleep and have the energy to conquer empires” - Caleb Hager
“CHICKEN TERIYAKI!!!!”- Gabe Hostetter
“You wanna know what separates The Don from The Donnie?”- Nick Visocky
“That thing you just did. Don’t do that”- Evan Meyers
“Recording”- Myself
“Yep”- Kacy Holm
“Please don’t make me drink anymore water.”- Kodi McGough
“I see an Idiot”- Chris Holm
“I’m literally dying right now”- Evangeline Wurst
1 note · View note
riichardwilson · 5 years ago
Text
How To Build A Blog With Next And MDX
About The Author
Ibrahima Ndaw is a Full-stack developer and blogger who loves JavaScript and also dabbles in UI/UX design. More about Ibrahima …
In this guide, we will be looking at Next.js, a popular React framework that offers a great developer experience and ships with all of the features you need for production. We will also build a blog, step by step, using Next.js and MDX. Finally, we’ll cover why you would opt for Next.js instead of “vanilla” React and alternatives such as Gatsby.
Next.js is a React framework that enables you to build static and dynamic apps quickly. It is production-ready and supports server-side rendering and static site generation out of the box, making Next.js apps fast and SEO Company-friendly.
In this tutorial, I will first explain what exactly Next.js is and why you’d use it instead of Create React App or Gatsby. Then, I’ll show you how to build a blog on which you can write and render posts using Next.js and MDX.
To get started, you’ll need some experience with React. Knowledge of Next.js would come handy but is not compulsory. This tutorial would benefit those who want to create a blog (personal or organizational) using Next.js or are still searching for what to use.
Let’s dive in.
What Is Next.js?
Next.js is a React framework created and maintained by Vercel. It’s built with React, Node.js, Babel, and Webpack. It is production-ready because it comes with a lot of great features that would usually be set up in a “vanilla” React app.
The Next.js framework can render apps on the server or export them statically. It doesn’t wait for the browser to load the JavaScript in order to show content, which makes Next.js apps SEO Company-friendly and blazing fast.
Why Use Next.js Over Create React App?
Create React App is a handy tool that offers a modern build setup with no configuration and without the hassle of having to set up Webpack, Babel, and so on or having to maintain their dependencies. It’s the recommended way to create React apps nowadays. It has a template for TypeScript and also comes with the React Testing Library.
However, if you want to build a multi-page app, then you’ll need to install an extra library, as if you were rendering a React app on the server. The extra setup could be a problem, and any packages installed could increase the final bundle size of your app.
This is exactly the problem that Next.js is intended to solve. It offers the best developer experience, with all of the things you need for production. It comes with several cool features:
Static exporting (pre-rendering) Next.js allows you to export your Next.js app at build time to static HTML that runs without a server. It is the recommended way to generate your website because it’s done at build time and not at each request.
Server-side rendering (pre-rendering) It pre-renders pages to HTML on the server upon every request.
Automatic code splitting Unlike React, Next.js splits code automatically and only loads the JavaScript needed, which makes the app fast.
File-system-based routing Next.js uses the file system to enable routing in the app, meaning that every file under the pages directory will be treated automatically as a route.
Hot reloading of code Next.js relies on React Fast Refresh to hot reload your code, offering a great developer experience.
Styling options The Next.js framework has built-in support for Styled JSX, CSS modules, Sass, LESS, and more.
Next.js Versus Gatsby
Gatsby is a static site generator built on top of React and GraphQL. It is popular and has a huge ecosystem that provides themes, plugins, recipes, and so on.
Gatsby and Next.js websites are super-fast because they are both rendered either on the server or statically, meaning that the JavaScript code does not wait for the browser to load. Let’s compare them according to the developer experience.
Gatsby is easy to start with, especially if you already know React. However, Gatsby uses GraphQL to query local data and pages. Using Gatsby to build this simple blog might be overkill because GraphQL has a learning curve, and the querying and build time of static pages would be a bit longer. If you built this same blog twice, first with Gatsby and then with Next.js, the one built with Next.js would be much faster at build time because it uses regular JavaScript to query local data and pages.
I hope you take advantage of the power of the Next.js framework and see why it’s so much handier than some alternatives. It’s also a great choice if your website relies heavily on SEO Company because your app will be fast and easy for Google robots to crawl. That’s the reason why we will be using Next.js in this article to build a blog with the MDX library.
Let’s start by setting up a new Next.js app.
Setting Up
There are two ways to create a Next.js app. We can set up a new app manually or use Create Next App. We’ll go for the latter because it’s the recommended way, and it will set up everything automatically for us.
To start a new app, run the following in the command-line interface (CLI):
npx create-next-app
Once the project is initialized, let’s structure the Next.js app as follows:
src ├── components | ├── BlogPost.js | ├── Header.js | ├── HeadPost.js | ├── Layout.js | └── Post.js ├── pages | ├── blog | | ├── post-1 | | | └── index.mdx | | ├── post-2 | | | └── index.mdx | | └── post-3 | | └── index.mdx | ├── index.js | └── \_app.js ├── getAllPosts.js ├── next.config.js ├── package.json ├── README.md └── yarn.lock
As you can see, our project has a simple file structure. There are three things to note:
_app.js allows us to append some content to the App.js component in order to make it global.
getAllPosts.js helps us to retrieve the blog posts from the folder pages/blog. By the way, you can name the file whatever you want.
next.config.js is the configuration file for our Next.js app.
I will come back to each file later and explain what it does. For now, let’s see the MDX package.
Installing the MDX Library
MDX is a format that lets us seamlessly write JSX and import components into our Markdown files. It enables us to write regular Markdown and embed React components in our files as well.
To enable MDX in the app, we need to install the @mdx-js/loader library. To do so, let’s first navigate to the root of the project and then run this command in the CLI:
yarn add @mdx-js/loader
Or, if you’re using npm:
npm install @mdx-js/loader
Next, install @next/mdx, which is a library specific to Next.js. Run this command in the CLI:
yarn add @next/mdx
Or, for npm:
npm install @next/mdx
Great! We are done setting up. Let’s get our hands dirty and code something meaningful.
Configuring the next.config.js File
const withMDX = require("@next/mdx")({ extension: /\.mdx?$/ }); module.exports = withMDX({ pageExtensions: ["js", "jsx", "md", "mdx"] });
Earlier in this tutorial, I said that files under the pages folder would be treated as pages/routes by Next.js at build time. By default, Next.js will just pick files with .js or .jsx extensions. That’s why we need a config file, to add some customizations to the default behavior of Next.js.
The next.config.js file tells the framework that files with .md or .mdx extensions should also be treated as pages/routes at build time because the blog folder that contains the articles lives in the pages directory.
That being said, we can start fetching the blog posts in the next part.
Fetching Blog Posts
One of the reasons why building a blog with Next.js is easy and simple is that you do not need GraphQL or the like to fetch local posts. You can just use regular JavaScript to get the data.
In getAllPosts.js:
function importAll(r) { return r.keys().map((fileName) => ({ link: fileName.substr(1).replace(/\/index\.mdx$/, ""), module: r(fileName) })); } export const posts = importAll( require.context("./pages/blog/", true, /\.mdx$/) );
This file can be intimidating at first. It’s a function that imports all MDX files from the folder pages/blog, and for each post it returns an object with the path of the file, without the extension (/post-1), and the data of the blog post.
With that in place, we can now build the components in order to style and show data in our Next.js app.
Building The Components
In components/Layout.js:
import Head from "next/head"; import Header from "./Header"; export default function Layout({ children, pageTitle, description }) { return ( <> <Head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta charSet="utf-8" /> <meta name="Description" content={description}></meta> <title>{pageTitle}</title> </Head> <main> <Header /> <div className="content">{children}</div> </main> </> ); }
Here, we have the Layout component, which we’ll be using as a wrapper for the blog. It receives the meta data to show in the head of the page and the component to be displayed.
In components/Post.js:
import Link from 'next/link' import { HeadPost } from './HeadPost' export const Post = ({ post }) => { const { link, module: { meta }, } = post return ( <article> <HeadPost meta={meta} /> <Link href={'/blog' + link}> <a>Read more →</a> </Link> </article> ) }
This component is responsible for displaying a preview of a blog post. It receives the post object to show as props. Next, we use destructuring to pull out the link of the post and the meta to show from the object. With that, we can now pass the data to the components and handle the routing with the Link component.
In components/BlogPost.js:
import { HeadPost } from './HeadPost' export default function BlogPost({ children, meta}) { return ( <> <HeadPost meta={meta} isBlogPost /> <article>{children}</article> </> ) }
The BlogPost component helps us to render a single article. It receives the post to show and its meta object.
So far, we have covered a lot — but we have no articles to show. Let’s fix that in the next section.
Writing Posts With MDX
import BlogPost from '../../../components/BlogPost' export const meta = { title: 'Introduction to Next.js', description: 'Getting started with the Next framework', date: 'Aug 04, 2020', readTime: 2 } export default ({ children }) => <BlogPost meta={meta}>{children}</BlogPost>; ## My Headline Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque maximus pellentesque dolor non egestas. In sed tristique elit. Cras vehicula, nisl vel ultricies gravida, augue nibh laoreet arcu, et tincidunt augue dui non elit. Vestibulum semper posuere magna, quis molestie mauris faucibus ut.
As you can see, we import the BlogPost component, which receives the meta and the body of the post.
The parameter children is the body of the blog post or, to be precise, everything that comes after the meta object. It is the function responsible for rendering the post.
With that change, we can move to the index.js file and display the posts on the home page.
Displaying Posts
import { Post } from "../components/Post"; import { posts } from "../getAllPosts"; export default function IndexPage() { return ( <> {posts.map((post) => ( <Post key={post.link} post={post} /> ))} </> ); }
Here, we start by importing the Post component and the posts fetched from the blog folder. Next, we loop through the array of articles, and for each post, we use the Post component to display it. That being done, we are now able to fetch the posts and display them on the page.
We are almost done. However, the Layout component is still not being used. We can use it here and wrap our components with it. But that won’t affect the articles pages. That’s where the _app.js file comes into play. Let’s use that in the next section.
Using the _app.js File
Here, the underscore symbol (_) is really important. If you omit it, Next.js will treat the file as a page/route.
import Layout from "../components/Layout"; export default function App({ Component, pageProps }) { return ( <Layout pageTitle="Blog" description="My Personal Blog"> <Component {...pageProps} /> </Layout> ); }
Next.js uses the App component to initialize pages. The purpose of this file is to override it and add some global styles to the project. If you have styles or data that need to be shared across the project, put them here.
We can now browse the project folder in the CLI and run the following command to preview the blog in the browser:
yarn dev
Or, in npm:
npm run dev
If you open http://localhost:3000 in the browser, you will be able to see this:
Great! Our blog looks good. We are done building the blog app with Next.js and MDX.
Conclusion
In this tutorial, we walked through Next.js by building a blog using the MDX library. The Next.js framework is a handy tool that makes React apps SEO Company-friendly and fast. It can be used to build static, dynamic JAMstack websites in no time, because it is production-ready and comes with some nice features. Next.js is used widely by big companies, and its performance keeps improving. It’s definitely something to check out for your next project.
You can preview the finished project on CodeSandbox.
Thanks for reading!
Resources
These useful resources will take you beyond the scope of this tutorial.
(ks, ra, al, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
source http://www.scpie.org/how-to-build-a-blog-with-next-and-mdx/ source https://scpie.tumblr.com/post/628812814141784064
0 notes
scpie · 5 years ago
Text
How To Build A Blog With Next And MDX
About The Author
Ibrahima Ndaw is a Full-stack developer and blogger who loves JavaScript and also dabbles in UI/UX design. More about Ibrahima …
In this guide, we will be looking at Next.js, a popular React framework that offers a great developer experience and ships with all of the features you need for production. We will also build a blog, step by step, using Next.js and MDX. Finally, we’ll cover why you would opt for Next.js instead of “vanilla” React and alternatives such as Gatsby.
Next.js is a React framework that enables you to build static and dynamic apps quickly. It is production-ready and supports server-side rendering and static site generation out of the box, making Next.js apps fast and SEO Company-friendly.
In this tutorial, I will first explain what exactly Next.js is and why you’d use it instead of Create React App or Gatsby. Then, I’ll show you how to build a blog on which you can write and render posts using Next.js and MDX.
To get started, you’ll need some experience with React. Knowledge of Next.js would come handy but is not compulsory. This tutorial would benefit those who want to create a blog (personal or organizational) using Next.js or are still searching for what to use.
Let’s dive in.
What Is Next.js?
Next.js is a React framework created and maintained by Vercel. It’s built with React, Node.js, Babel, and Webpack. It is production-ready because it comes with a lot of great features that would usually be set up in a “vanilla” React app.
The Next.js framework can render apps on the server or export them statically. It doesn’t wait for the browser to load the JavaScript in order to show content, which makes Next.js apps SEO Company-friendly and blazing fast.
Why Use Next.js Over Create React App?
Create React App is a handy tool that offers a modern build setup with no configuration and without the hassle of having to set up Webpack, Babel, and so on or having to maintain their dependencies. It’s the recommended way to create React apps nowadays. It has a template for TypeScript and also comes with the React Testing Library.
However, if you want to build a multi-page app, then you’ll need to install an extra library, as if you were rendering a React app on the server. The extra setup could be a problem, and any packages installed could increase the final bundle size of your app.
This is exactly the problem that Next.js is intended to solve. It offers the best developer experience, with all of the things you need for production. It comes with several cool features:
Static exporting (pre-rendering) Next.js allows you to export your Next.js app at build time to static HTML that runs without a server. It is the recommended way to generate your website because it’s done at build time and not at each request.
Server-side rendering (pre-rendering) It pre-renders pages to HTML on the server upon every request.
Automatic code splitting Unlike React, Next.js splits code automatically and only loads the JavaScript needed, which makes the app fast.
File-system-based routing Next.js uses the file system to enable routing in the app, meaning that every file under the pages directory will be treated automatically as a route.
Hot reloading of code Next.js relies on React Fast Refresh to hot reload your code, offering a great developer experience.
Styling options The Next.js framework has built-in support for Styled JSX, CSS modules, Sass, LESS, and more.
Next.js Versus Gatsby
Gatsby is a static site generator built on top of React and GraphQL. It is popular and has a huge ecosystem that provides themes, plugins, recipes, and so on.
Gatsby and Next.js websites are super-fast because they are both rendered either on the server or statically, meaning that the JavaScript code does not wait for the browser to load. Let’s compare them according to the developer experience.
Gatsby is easy to start with, especially if you already know React. However, Gatsby uses GraphQL to query local data and pages. Using Gatsby to build this simple blog might be overkill because GraphQL has a learning curve, and the querying and build time of static pages would be a bit longer. If you built this same blog twice, first with Gatsby and then with Next.js, the one built with Next.js would be much faster at build time because it uses regular JavaScript to query local data and pages.
I hope you take advantage of the power of the Next.js framework and see why it’s so much handier than some alternatives. It’s also a great choice if your website relies heavily on SEO Company because your app will be fast and easy for Google robots to crawl. That’s the reason why we will be using Next.js in this article to build a blog with the MDX library.
Let’s start by setting up a new Next.js app.
Setting Up
There are two ways to create a Next.js app. We can set up a new app manually or use Create Next App. We’ll go for the latter because it’s the recommended way, and it will set up everything automatically for us.
To start a new app, run the following in the command-line interface (CLI):
npx create-next-app
Once the project is initialized, let’s structure the Next.js app as follows:
src ├── components | ├── BlogPost.js | ├── Header.js | ├── HeadPost.js | ├── Layout.js | └── Post.js ├── pages | ├── blog | | ├── post-1 | | | └── index.mdx | | ├── post-2 | | | └── index.mdx | | └── post-3 | | └── index.mdx | ├── index.js | └── \_app.js ├── getAllPosts.js ├── next.config.js ├── package.json ├── README.md └── yarn.lock
As you can see, our project has a simple file structure. There are three things to note:
_app.js allows us to append some content to the App.js component in order to make it global.
getAllPosts.js helps us to retrieve the blog posts from the folder pages/blog. By the way, you can name the file whatever you want.
next.config.js is the configuration file for our Next.js app.
I will come back to each file later and explain what it does. For now, let’s see the MDX package.
Installing the MDX Library
MDX is a format that lets us seamlessly write JSX and import components into our Markdown files. It enables us to write regular Markdown and embed React components in our files as well.
To enable MDX in the app, we need to install the @mdx-js/loader library. To do so, let’s first navigate to the root of the project and then run this command in the CLI:
yarn add @mdx-js/loader
Or, if you’re using npm:
npm install @mdx-js/loader
Next, install @next/mdx, which is a library specific to Next.js. Run this command in the CLI:
yarn add @next/mdx
Or, for npm:
npm install @next/mdx
Great! We are done setting up. Let’s get our hands dirty and code something meaningful.
Configuring the next.config.js File
const withMDX = require("@next/mdx")({ extension: /\.mdx?$/ }); module.exports = withMDX({ pageExtensions: ["js", "jsx", "md", "mdx"] });
Earlier in this tutorial, I said that files under the pages folder would be treated as pages/routes by Next.js at build time. By default, Next.js will just pick files with .js or .jsx extensions. That’s why we need a config file, to add some customizations to the default behavior of Next.js.
The next.config.js file tells the framework that files with .md or .mdx extensions should also be treated as pages/routes at build time because the blog folder that contains the articles lives in the pages directory.
That being said, we can start fetching the blog posts in the next part.
Fetching Blog Posts
One of the reasons why building a blog with Next.js is easy and simple is that you do not need GraphQL or the like to fetch local posts. You can just use regular JavaScript to get the data.
In getAllPosts.js:
function importAll(r) { return r.keys().map((fileName) => ({ link: fileName.substr(1).replace(/\/index\.mdx$/, ""), module: r(fileName) })); } export const posts = importAll( require.context("./pages/blog/", true, /\.mdx$/) );
This file can be intimidating at first. It’s a function that imports all MDX files from the folder pages/blog, and for each post it returns an object with the path of the file, without the extension (/post-1), and the data of the blog post.
With that in place, we can now build the components in order to style and show data in our Next.js app.
Building The Components
In components/Layout.js:
import Head from "next/head"; import Header from "./Header"; export default function Layout({ children, pageTitle, description }) { return ( <> <Head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta charSet="utf-8" /> <meta name="Description" content={description}></meta> <title>{pageTitle}</title> </Head> <main> <Header /> <div className="content">{children}</div> </main> </> ); }
Here, we have the Layout component, which we’ll be using as a wrapper for the blog. It receives the meta data to show in the head of the page and the component to be displayed.
In components/Post.js:
import Link from 'next/link' import { HeadPost } from './HeadPost' export const Post = ({ post }) => { const { link, module: { meta }, } = post return ( <article> <HeadPost meta={meta} /> <Link href={'/blog' + link}> <a>Read more →</a> </Link> </article> ) }
This component is responsible for displaying a preview of a blog post. It receives the post object to show as props. Next, we use destructuring to pull out the link of the post and the meta to show from the object. With that, we can now pass the data to the components and handle the routing with the Link component.
In components/BlogPost.js:
import { HeadPost } from './HeadPost' export default function BlogPost({ children, meta}) { return ( <> <HeadPost meta={meta} isBlogPost /> <article>{children}</article> </> ) }
The BlogPost component helps us to render a single article. It receives the post to show and its meta object.
So far, we have covered a lot — but we have no articles to show. Let’s fix that in the next section.
Writing Posts With MDX
import BlogPost from '../../../components/BlogPost' export const meta = { title: 'Introduction to Next.js', description: 'Getting started with the Next framework', date: 'Aug 04, 2020', readTime: 2 } export default ({ children }) => <BlogPost meta={meta}>{children}</BlogPost>; ## My Headline Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque maximus pellentesque dolor non egestas. In sed tristique elit. Cras vehicula, nisl vel ultricies gravida, augue nibh laoreet arcu, et tincidunt augue dui non elit. Vestibulum semper posuere magna, quis molestie mauris faucibus ut.
As you can see, we import the BlogPost component, which receives the meta and the body of the post.
The parameter children is the body of the blog post or, to be precise, everything that comes after the meta object. It is the function responsible for rendering the post.
With that change, we can move to the index.js file and display the posts on the home page.
Displaying Posts
import { Post } from "../components/Post"; import { posts } from "../getAllPosts"; export default function IndexPage() { return ( <> {posts.map((post) => ( <Post key={post.link} post={post} /> ))} </> ); }
Here, we start by importing the Post component and the posts fetched from the blog folder. Next, we loop through the array of articles, and for each post, we use the Post component to display it. That being done, we are now able to fetch the posts and display them on the page.
We are almost done. However, the Layout component is still not being used. We can use it here and wrap our components with it. But that won’t affect the articles pages. That’s where the _app.js file comes into play. Let’s use that in the next section.
Using the _app.js File
Here, the underscore symbol (_) is really important. If you omit it, Next.js will treat the file as a page/route.
import Layout from "../components/Layout"; export default function App({ Component, pageProps }) { return ( <Layout pageTitle="Blog" description="My Personal Blog"> <Component {...pageProps} /> </Layout> ); }
Next.js uses the App component to initialize pages. The purpose of this file is to override it and add some global styles to the project. If you have styles or data that need to be shared across the project, put them here.
We can now browse the project folder in the CLI and run the following command to preview the blog in the browser:
yarn dev
Or, in npm:
npm run dev
If you open http://localhost:3000 in the browser, you will be able to see this:
Great! Our blog looks good. We are done building the blog app with Next.js and MDX.
Conclusion
In this tutorial, we walked through Next.js by building a blog using the MDX library. The Next.js framework is a handy tool that makes React apps SEO Company-friendly and fast. It can be used to build static, dynamic JAMstack websites in no time, because it is production-ready and comes with some nice features. Next.js is used widely by big companies, and its performance keeps improving. It’s definitely something to check out for your next project.
You can preview the finished project on CodeSandbox.
Thanks for reading!
Resources
These useful resources will take you beyond the scope of this tutorial.
(ks, ra, al, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
source http://www.scpie.org/how-to-build-a-blog-with-next-and-mdx/
0 notes